boost::asio::tcp::socket Закрытие и отмена без вызова обработчиков

Я пишу сервер с библиотекой asio от boost. Сервер обрабатывает множество одновременных подключений, используя набор объектов Connection (класс-оболочку для boost::asio::tcp::socket). В классе Connection сокет постоянно считывается с помощью socket.async_read_some(...) и всякий раз, когда обработчик чтения вызывается с новыми данными, socket.async_read_some() немедленно вызывается снова, чтобы прочитать больше данных.

Теперь сервер может решить отключить клиента по какой-то причине, поэтому естественным будет вызвать connection.close(), который, в свою очередь, вызовет socket.close(), что приведет к тому, что все ожидающие асинхронные операции будут завершены. отменен. Это приводит к тому, что обработчик чтения (привязанный к методу в классе Connection) вызывается с помощью boost::asio::error::operation_aborted. И моя проблема в том, что я не хочу, чтобы это произошло.

После socket.close() я хотел бы уничтожить сокет и соединение, а затем удалить его указатель из списка активных клиентов сервера. Однако обработчик чтения не будет вызываться до следующей итерации io_service.run(), что означает, что я не могу немедленно уничтожить сокет или обработчик чтения, который я передал в socket.async_read_some(), пока обработчик не будет вызван с помощью ошибка. Так что я должен как-то отсрочить уничтожение этих объектов; это раздражает.

Существует ли безопасный способ либо

  • отменить ожидающие асинхронные операции безвызова какого-либо обработчика, чтобы я мог безопасно уничтожить сокет сразу после socket.close(), либо
  • безопасно знать, когда потенциально больше нельзя вызывать обработчиков

Или я подхожу к этому совершенно неправильно?

6
задан jlh 16 May 2012 в 22:11
поделиться