ソケットがシャットダウン/クローズされてから削除された場合 (つまり、デストラクタが実行され、メモリが解放された場合)、完了ハンドラはどうなりますか? 私の知る限り、それが閉じられた後、すべての完了ハンドラは、次回ループがポーリングされたときにエラーコードを受け取ります。しかし、ハンドラーが実行される前に socked が削除された場合はどうなるでしょうか? イベントハンドラをディスパッチする前にソケットを削除してもよろしいですか?
2 に答える
未処理のハンドラが実行される前にソケットを削除しても安全です。未処理の操作のハンドラは、 で呼び出されるように設定されますboost::asio::error::operation_aborted
。ハンドラーが削除されたソケットで操作を呼び出さないようにするのは、アプリケーション コードの責任です。
詳細については、ソケットなどの IO オブジェクトを破棄すると、IO オブジェクトのサービスが破棄されます。非同期操作を暗黙的にキャンセルする要件SocketService
状態。destroy()
未処理の非同期操作は、できるだけ早く完了しようとします。これにより、取り消された操作のハンドラにエラー コードが渡さboost::asio::error::operation_aborted
れ、io_service
. これらのハンドラはio_service
、イベント ループを処理するスレッドから呼び出された場合、またはio_service
が破棄された場合に、 から削除されます。
すべてのハンドラが呼び出されることが保証されています。ソケットが閉じられた場合 - ハンドラーが何らかのエラー コードで呼び出されます。
通常、boost::enable_shared_from_this を使用してオブジェクトの有効期間を制御するには、この保証を使用する必要があります。
class Writer : boost::enable_shared_from_this<Writer>
{
boost::asio::socket scoket_;
...
void StartWrite()
{
boost::asio::async_write(socket_,
boost::asio::buffer(buffer_, bytes_sent_),
boost::bind(&Writer::Handler, shared_from_this,
boost::asio::placeholders::error));
...
void Handler(boost::system::error_code const& err) {...}
このアプローチでは、ソケット オブジェクトは保留中のすべてのハンドラーよりも長く存続します。