Win32 API 日本語リファレンス
ホーム › Networking.WinSock › LPFN_RIOCREATECOMPLETIONQUEUE

LPFN_RIOCREATECOMPLETIONQUEUE

コールバック

シグネチャ

RIO_CQ LPFN_RIOCREATECOMPLETIONQUEUE(
    DWORD QueueSize,
    RIO_NOTIFICATION_COMPLETION* NotificationCompletion
);

パラメーター

フィールド型説明
QueueSizeDWORD作成する完了キューのサイズ (エントリ数)。
NotificationCompletionRIO_NOTIFICATION_COMPLETION*

RIO_NOTIFICATION_COMPLETION 構造体の Type メンバーに基づいて使用する、通知完了の種類 (I/O 完了またはイベント通知) です。

Type メンバーに RIO_EVENT_COMPLETION が設定されている場合は、RIO_NOTIFICATION_COMPLETION 構造体の Event メンバーを設定する必要があります。

Type メンバーに RIO_IOCP_COMPLETION が設定されている場合は、RIO_NOTIFICATION_COMPLETION 構造体の Iocp メンバーを設定する必要があり、さらに RIO_NOTIFICATION_COMPLETION 構造体の Iocp.Overlapped メンバーを NULL 以外にする必要があります。

NotificationCompletion パラメーターが NULL の場合は、通知完了を使用せず、完了の判定にポーリングを使用する必要があることを示します。

公式ドキュメント

RIOCreateCompletionQueue 関数は、Winsock の登録された I/O 拡張機能で使用する、指定したサイズの I/O 完了キューを作成します。

戻り値

エラーが発生しなかった場合、RIOCreateCompletionQueue 関数は新しい完了キューを参照する記述子を返します。それ以外の場合は RIO_INVALID_CQ が返され、WSAGetLastError 関数を呼び出すことで具体的なエラーコードを取得できます。

戻り値 説明
WSAEFAULT
呼び出しでポインター引数を使用しようとした際に、システムが無効なポインターアドレスを検出しました。
WSAEINVAL
無効なパラメーターが関数に渡されました。
このエラーは、QueueSize パラメーターが 1 未満であるか、Mswsockdef.h ヘッダーファイルで定義されている RIO_MAX_CQ_SIZE より大きい場合に返されます。
WSAENOBUFS
十分なメモリを割り当てられませんでした。このエラーは、QueueSize パラメーターで要求された完了キューを割り当てるためのメモリが不足していた場合に返されます。

解説(Remarks)

RIOCreateCompletionQueue 関数は、指定したサイズの I/O 完了キューを作成します。完了キューのサイズにより、その完了キューに関連付けできる登録された I/O ソケットの集合が制限されます。詳細については、RIOCreateRequestQueue 関数を参照してください。

RIO_CQ を作成する際、NotificationCompletion パラメーターが指す RIO_NOTIFICATION_COMPLETION 構造体によって、アプリケーションが完了キューの通知をどのように受け取るかが決まります。完了キューの作成時に RIO_NOTIFICATION_COMPLETION 構造体を指定した場合、アプリケーションは RIONotify 関数を呼び出して完了キューの通知を要求できます。通常、この通知は完了キューが空でないときに発生します。これは即座に発生することも、次の完了エントリが完了キューに挿入されたときに発生することもあります。ただし、送信要求および受信要求には RIO_MSG_DONT_NOTIFY フラグを設定できます。そのような要求の結果として完了キューの通知がトリガーされることはありません。完了キューに RIO_MSG_DONT_NOTIFY フラグが設定されたエントリしか含まれていない場合、完了キューの通知はトリガーされません。また、新しいエントリが完了キューに入ったときに完了キューの通知がトリガーされるのは、対応する要求に RIO_MSG_DONT_NOTIFY フラグが設定されていなかった場合のみです。完了した要求は、RIODequeueCompletion 関数によるポーリングで引き続き取得できます。完了キューの通知が一度発行された後、別の完了キュー通知を受け取るには、アプリケーションは RIONotify 関数を呼び出す必要があります。完了キューの通知が発生すると、アプリケーションは通常 RIODequeueCompletion 関数を呼び出して、完了した送信要求または受信要求をデキューします。

完了キューの通知には 2 つの方法があります。

RIO_NOTIFICATION_COMPLETION 構造体の Type メンバーに RIO_EVENT_COMPLETION が設定されている場合は、完了キューの通知を知らせるためにイベントハンドルが使用されます。イベントハンドルは、RIOCreateCompletionQueue 関数に渡す RIO_NOTIFICATION_COMPLETION 構造体の EventNotify.EventHandle メンバーとして指定します。Event.EventHandle メンバーには、WSACreateEvent 関数または CreateEvent 関数で作成したイベントのハンドルを格納します。RIONotify の完了を受け取るには、アプリケーションは WSAWaitForMultipleEvents または同様の待機ルーチンを使用して、指定したイベントハンドルを待機します。この RIO_CQ に対する RIONotify 関数の完了により、イベントがシグナル状態になります。RIOCreateCompletionQueue 関数に渡す RIO_NOTIFICATION_COMPLETION 構造体の Event.NotifyReset メンバーは、RIONotify 関数の呼び出しの一部としてイベントをリセットするかどうかを示します。アプリケーションがイベントをリセットして再利用する場合は、Event.NotifyReset メンバーに 0 以外の値を設定することでオーバーヘッドを削減できます。これにより、通知が発生したときに RIONotify 関数によってイベントが自動的にリセットされます。その結果、RIONotify 関数の呼び出しの間に WSAResetEvent 関数を呼び出してイベントをリセットする必要がなくなります。

RIO_NOTIFICATION_COMPLETION 構造体の Type メンバーに RIO_IOCP_COMPLETION が設定されている場合は、完了キューの通知を知らせるために I/O 完了ポートが使用されます。I/O 完了ポートのハンドルは、RIOCreateCompletionQueue 関数に渡す RIO_NOTIFICATION_COMPLETION 構造体の Iocp.IocpHandle メンバーとして指定します。この RIO_CQ に対する RIONotify 関数の完了により、I/O 完了ポートにエントリがキューイングされ、GetQueuedCompletionStatus 関数または GetQueuedCompletionStatusEx 関数で取得できます。キューイングされたエントリでは、返される lpCompletionKey パラメーターの値が RIO_NOTIFICATION_COMPLETION 構造体の Iocp.CompletionKey メンバーで指定した値に設定され、RIO_NOTIFICATION_COMPLETION 構造体の Iocp.Overlapped メンバーは NULL 以外の値になります。

用途の観点では、完了キューの通知は、待機中のアプリケーションスレッドを起こして、そのスレッドが完了キューを調べられるようにするためのものです。スレッドを起こしてスケジュールするにはコストがかかるため、これが頻繁に発生するとアプリケーションのパフォーマンスに悪影響を与えます。RIO_MSG_DONT_NOTIFY フラグは、アプリケーションがこれらのイベントの頻度を制御し、パフォーマンスへの影響を抑えられるように用意されています。

メモ

効率化のため、完了キュー (RIO_CQ 構造体) と要求キュー (RIO_RQ 構造体) へのアクセスは、同期プリミティブによって保護されていません。複数のスレッドから完了キューまたは要求キューにアクセスする必要がある場合は、クリティカルセクション、スリムリーダーライターロック、または同様の仕組みでアクセスを調整してください。単一のスレッドからアクセスする場合、このロックは不要です。異なるスレッドが別々の要求キュー/完了キューにアクセスする場合は、ロックなしで行えます。同期が必要になるのは、複数のスレッドが同じキューにアクセスしようとする場合だけです。また、複数のスレッドが同じソケットで送信と受信を発行する場合も、送信操作と受信操作はそのソケットの要求キューを使用するため、同期が必要です。

メモ

RIOCreateCompletionQueue 関数への関数ポインターは、SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER オペコードを指定して WSAIoctl 関数を呼び出し、実行時に取得する必要があります。WSAIoctl 関数に渡す入力バッファーには、Winsock の登録された I/O 拡張関数を識別する値を持つグローバル一意識別子 (GUID) である WSAID_MULTIPLE_RIO を格納する必要があります。成功した場合、WSAIoctl 関数が返す出力には、Winsock の登録された I/O 拡張関数へのポインターを含む RIO_EXTENSION_FUNCTION_TABLE 構造体へのポインターが格納されます。SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL は Ws2def.h ヘッダーファイルで定義されています。WSAID_MULTIPLE_RIO GUID は Mswsock.h ヘッダーファイルで定義されています。

Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされます。

Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)