I am using Boost asio to open several sockets I use a collection with shared pointers to a custom class with all that socket info. This class also has the handle_read
function for async_receive
as I need to do different things with each receive and I can not bind with extra parameters.
The problem I am having is that when I close the socket I delete the last reference to that pointer so the handle_read
function is called without any valid reference as this and then the code just breaks.
void SocketsAPI::do_close(const SocketInfo socket)
{
log("do_close");
if (!socket.m_socket || !socket.m_socket->is_open()) {
return;
}
boost::system::error_code errorcode;
socket.m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode) {
trace("Closing failed: ", errorcode.message());
}
socket.m_socket->close(errorcode);
if (errorcode) {
trace("Closing2 failed: ", errorcode.message());
}
mapType::iterator iter = sockets.find(socket.key);
if (iter != sockets.end()) {
sockets.erase (iter);
}
log("do_close end");
}
Indeed I don't want the handle_read
function to be called but I am unable to avoid it, and what it is worse in a multithreaded implementation (several threads calling io_service.run()
) the handle_read
will be called while the close is still being processed so "this" object will be freed in any point of the handler.