I am writing a server with boost asio library. The server handles many concurrent connections using a collection of Connection objects (the wrapper class around boost :: asio :: tcp :: socket). In the Connection class, the socket is constantly read using socket.async_read_some (...) and whenever the read handler is called with new data, socket.async_read_some () is immediately called again to get more data.
Now the server can decide to disconnect the client for some reason, so it is natural to call connection.close (), which in turn calls socket.close (), which will cause all pending async operations to be canceled. This causes the read handler (associated with the method inside the Connection class) to be called with boost :: asio :: error :: operation_aborted. And my problem: I do not want this to happen.
After socket.close (), I would like to destroy the socket and connection, and then remove its pointer from the list of active server clients. However, the read handler will not be called until the next iteration of io_service.run (), which means that I cannot immediately destroy the socket or read handler that I passed socket.async_read_some () until the handler was called with an error. Therefore, I must somehow postpone the destruction of these objects; it is annoying.
Is there a safe way to
- Cancel pending async operations without calling the handler, so I can safely destroy the socket right after socket.close () or
- to safely know when more handlers could potentially be called
Or do I completely disagree with this?
source share