LPWSPCANCELBLOCKINGCALL
コールバックシグネチャ
INT LPWSPCANCELBLOCKINGCALL(
INT* lpErrno
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| lpErrno | INT* | エラーコードへのポインター。 |
公式ドキュメント
LPWSPCancelBlockingCall 関数は、現在進行中のブロッキング呼び出しをキャンセルします。
戻り値
LPWSPCancelBlockingCall が返す値は、操作が正常にキャンセルされた場合は 0 です。それ以外の場合は SOCKET_ERROR が返され、具体的なエラーコードは lpErrno で取得できます。
| エラーコード | 意味 |
|---|---|
| ネットワークサブシステムが停止しています。 | |
| 未処理のブロッキング呼び出しが存在しないことを示します。 |
解説(Remarks)
この関数は、このスレッドで未処理となっているブロッキング操作をキャンセルします。通常、次の 2 つの状況で使用されます。
- サービスプロバイダーが疑似ブロッキングを実装している間に受信したメッセージを、Windows Sockets SPI クライアントが処理している場合。この場合、WSAIsBlocking は true になります。
- ブロッキング呼び出しが進行中で、Winsock サービスプロバイダーが (WPUQueryBlockingCallback から取得したコールバック関数を通じて) Winsock SPI クライアントのブロッキングフック関数をコールバックし、そのフック関数がこの関数を呼び出している場合。このような状況は、たとえば完了までに長い時間を要する操作に対して Cancel オプションを実装する場合などに発生します。
いずれの場合も、元のブロッキング呼び出しはできるだけ早くエラー WSAEINTR で終了します。(1 つ目のケースでは、Windows のメッセージスケジューリングによって制御が Winsock 内の疑似ブロッキングルーチンに戻るまで終了は行われません。2 つ目のケースでは、ブロッキングフック関数が完了した時点でブロッキング呼び出しが終了します。)
ブロッキングモードの LPWSPConnect 操作の場合、Winsock はできるだけ早くブロッキング呼び出しを終了しますが、接続が完了する (そしてリセットされる) かタイムアウトするまで、ソケットのリソースを解放することはできません。これが問題として現れるのは、Winsock SPI クライアントが直ちに新しいソケットを開こうとした場合 (利用可能なソケットが無いとき) や、LPWSPConnect 呼び出しで同じピアに接続しようとした場合に限られます。
LPWSPAccept または LPWSPSelect の呼び出しをキャンセルしても、これらの呼び出しに渡されたソケットに悪影響はありません。失敗するのはその特定の呼び出しだけであり、キャンセル前に有効だった操作はキャンセル後も有効で、ソケットの状態も一切影響を受けません。
LPWSPAccept および LPWSPSelect 以外の操作をキャンセルすると、ソケットが不定の状態になることがあります。Winsock SPI クライアントがソケット上のブロッキング操作をキャンセルした場合、そのソケットに対して Winsock SPI クライアントが実行できる操作は LPWSPCloseSocket の呼び出しだけです。ただし、一部の Winsock サービスプロバイダーでは他の操作も動作する場合があります。Winsock SPI クライアントに最大限の移植性が必要な場合は、キャンセル操作の後に操作を実行することに依存しないよう注意してください。Winsock SPI クライアントは、SO_LINGER のタイムアウトを 0 に設定して LPWSPCloseSocket を呼び出すことで、接続をリセットできます。
キャンセル操作によって SOCK_STREAM のデータストリームの整合性が少しでも損なわれた場合、Winsock プロバイダーは接続をリセットし、LPWSPCloseSocket 以外の以降のすべての操作を WSAECONNABORTED で失敗させます。
ブロッキング状態のネットワーク操作がキャンセルされる前に完了した場合、LPWSPCancelBlockingCall が成功を返しても問題ありません。この場合、ブロッキング操作は LPWSPCancelBlockingCall が呼び出されなかったかのように正常に復帰します。Winsock SPI クライアントが操作の実際のキャンセルを確認する唯一の方法は、ブロッキング呼び出しからの戻りコードが WSAEINTR であるかどうかを確認することです。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)