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()
)でさらに悪いことにhandle_read
、クローズがまだ処理されている間に呼び出されるので、「この」オブジェクトはハンドラーの任意のポイントで解放されます。