在读处理程序上释放的Boost绑定对象

时间:2013-03-15 18:11:59

标签: sockets boost-asio boost-thread

我正在使用Boost asio打开几个套接字我使用一个集合,其中包含指向具有所有套接字信息的自定义类的共享指针。这个类还有handle_read async_receive函数,因为我需要对每个接收做不同的事情,我不能用额外的参数绑定。

我遇到的问题是,当我关闭套接字时,我删除了对该指针的最后一个引用,因此调用handle_read函数时没有任何有效的引用,然后代码就会中断。

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");
}

确实我不希望调用handle_read函数,但是我无法避免它,以及在多线程实现(多个线程调用io_service.run()){{1在关闭仍在处理时将被调用,因此“this”对象将在处理程序的任何一点被释放。

1 个答案:

答案 0 :(得分:2)

听起来你很接近,但还不太了解通常使用Boost.Asio异步方法的应用程序完成的共享所有权语义。您需要在binding your callback处理程序时使用shared_from_this(),以确保它们在异步操作期间保持在作用域内。 <{1}}文档explains this非常好。

当您需要提前停止异步操作时,cancel it而不是关闭io_service::~io_service()方法中的套接字。然后,您的回调将被赋予错误代码boost::asio::error::operation_aborted,您可以使用它来做出适当的反应。


  

在关闭仍然存在时将调用SocketsAPI::do_close()   处理后,“this”对象将在处理程序的任何位置释放。

这实际上是一个单独的问题,您需要将handle_read s ensure exclusive access用于处理程序回调中的数据结构。