KeWaitForMultipleObjects 関数 (wdm.h)

KeWaitForMultipleObjects ルーチンは、多数のディスパッチャー オブジェクトの一部またはすべてがシグナル状態または (オプションで) 待機がタイムアウトするまで、現在のスレッドをアラート可能または非アラート可能な待機状態にします。

構文

NTSTATUS
KeWaitForMultipleObjects (
    ULONG Count,
    PVOID Object[],
    WaitType,
    KWAIT_REASON WaitReason,
    KPROCESSOR_MODE WaitMode,
    BOOLEAN Alertable,
    PLARGE_INTEGER Timeout,
    PKWAIT_BLOCK WaitBlockArray
    );

パラメーター

[in] Count

待機するオブジェクトの数。 このパラメーターは、 Object パラメーターが指す配列内の要素の数を指定します。

[in] Object

呼び出し元がストレージを提供するディスパッチャー オブジェクト (イベント、ミューテックス、セマフォ、スレッド、タイマー) へのポインターの配列へのポインター。 ポインター配列とディスパッチャー オブジェクトの両方が、非ページ システム メモリに存在する必要があります。 詳細については、「解説」を参照してください。

[in] WaitType

実行する待機操作の種類。 WaitAll を指定します。指定したすべてのオブジェクトが、待機が満たされる前にシグナル状態を取得する必要があることを示します。または WaitAny。待機が満たされる前に、いずれかのオブジェクトがシグナル状態を取得する必要があることを示します。

[in] WaitReason

待機の理由。 ドライバーは、この値を Executive に設定するか、ドライバーがユーザーの代わりに作業を行っていて、ユーザー スレッドのコンテキストで実行されている場合は UserRequest に設定する必要があります。

[in] WaitMode

呼び出し元が KernelMode または UserMode で待機するかどうか。 中間レベルと下位レベルのドライバーでは 、KernelMode を指定する必要があります。 待機しているオブジェクトのセットにミューテックスが含まれている場合、呼び出し元は KernelMode を指定する必要があります。

[in] Alertable

待機中の状態でスレッドを警告できるかどうかを示すブール値。

[in, optional] Timeout

待機が完了する 100 ナノ秒単位の絶対時間または相対時間を指定するタイムアウト値へのポインター。

正の値は、1601 年 1 月 1 日を基準とした絶対時間を指定します。 負の値は、現在の時刻を基準とした間隔を指定します。 絶対有効期限は、システム時刻の変更を追跡します。相対有効期限は、システム時間の変更の影響を受けません。

*Timeout = 0 の場合、ルーチンは待機せずにを返します。 呼び出し元が NULL ポインターを提供する場合、ディスパッチャー オブジェクトの一部またはすべてがシグナル状態に設定されるまで、ルーチンは無期限に待機します。 詳細については、「解説」を参照してください。

[out, optional] WaitBlockArray

呼び出し元によって割り当てられた KWAIT_BLOCK 配列へのポインター。 Count<= THREAD_WAIT_OBJECTSの場合、WaitBlockArrayNULL にすることができます。 それ以外の場合、このパラメーターは sizeof(KWAIT_BLOCK) * Count バイトのメモリ バッファーを指 必要があります。 このルーチンは、待機操作の実行中にレコードを保持するためにこのバッファーを使用します。 WaitBlockArray バッファーは、非ページ システム メモリに存在する必要があります。 詳細については、「解説」を参照してください。

戻り値

KeWaitForMultipleObjects は、 次のいずれかを返すことができます。

リターン コード 説明
STATUS_SUCCESS 呼び出し元が WaitType パラメーターに WaitAll を指定し、 Object 配列内のすべてのディスパッチャー オブジェクトがシグナル状態に設定されています。
STATUS_ALERTED 呼び出し元のスレッドにアラートを配信するための待機が中断されました。
STATUS_USER_APC ユーザー非同期プロシージャ呼び出し (APC) を呼び出し元スレッドに配信するための待機が中断されました。
STATUS_TIMEOUT 指定した待機条件のセットが満たされる前にタイムアウトが発生しました。 この値は、0 の明示的なタイムアウト値が指定されているが、指定された待機条件のセットをすぐに満たすことができない場合に返すことができます。
STATUS_WAIT_63 による STATUS_WAIT_0 呼び出し元が WaitTypeWaitAny を指定し、Object 配列内のディスパッチャー オブジェクトの 1 つがシグナル状態に設定されています。 戻り値の下位 6 ビットは、待機を満たすオブジェクトの 0 から始まるインデックスをエンコードします。
STATUS_ABANDONED_WAIT_63 による STATUS_ABANDONED_WAIT_0 呼び出し元が、破棄されたミューテックスを待機しようとしました。 戻り値の下位 6 ビットは、 Object 配列内のミューテックスの 0 から始まるインデックスをエンコードします。

NT_SUCCESS マクロでは、これらすべての状態値が "success" 値として認識されることに注意してください。

注釈

各スレッド オブジェクトには、複数のオブジェクトが同時に設定されるのを待機するために使用できる待機ブロックの組み込み配列があります。 待機ブロックの組み込み配列は、追加の待機ブロックストレージを割り当てず、後で割り当てを解除する必要がないため、可能な限り、待機ブロックの組み込み配列を複数待機操作で使用する必要があります。 ただし、同時に待機する必要があるオブジェクトの数が組み込みの待機ブロックの数を超える場合は、 WaitBlockArray パラメーターを使用して、待機操作で使用する待機ブロックの代替セットを指定します。 ドライバーは 、WaitBlockArray に十分な大きさのメモリ バッファーを割り当てる必要があります。 バッファーを初期化する必要はありません。ただし、非ページ システム メモリから割り当てる必要があります。 WaitMode パラメーターが UserMode の場合、スタックがメモリからスワップされる可能性があるため、WaitBlockArray バッファーをローカル スタックに割り当ててはなりません。 ドライバーは、このバッファーを不透明な構造体として扱うことができますし、ルーチンが返された後にそれを解放できます。 Count> MAXIMUM_WAIT_OBJECTSまたは WaitBlockArrayNULLCount> THREAD_WAIT_OBJECTSの場合、システムはバグ チェック 0xC (MAXIMUM_WAIT_OBJECTS_EXCEEDED) を発行します。

指定された各オブジェクトの現在の状態を調べて、待機をすぐに満たすことができるかどうかを判断します。 オブジェクトに対して必要な副作用が実行された場合は、適切な値が返されます。

待機をすぐに満たすことができない場合、タイムアウト値または 0 以外のタイムアウト値が指定されていない場合、現在のスレッドは待機状態になり、現在のプロセッサで実行するために新しいスレッドが選択されます。 Timeout が指定されていない場合、呼び出し元のスレッドは、Object および WaitType で指定された条件が満たされるまで待機状態のままになります。

Timeout を指定した場合、指定された間隔の有効期限が切れたときに指定された待機条件が満たされない場合、待機は自動的に満たされます。

タイムアウト値が 0 の場合、ミューテックスの取得と同様に、待機状態のセットをテストし、待機をすぐに満たすことができる場合は条件付きで副作用を実行できます。

タイムアウト間隔はシステム クロックに対して測定され、オペレーティング システムがタイムアウト間隔の終了を検出できる精度は、システム クロックの粒度によって制限されます。 詳細については、「タイマーの 精度」を参照してください。

Alertable パラメーターは、スレッドを警告できるタイミングと、その待機状態が結果として中止されるタイミングを決定します。 詳細については、「 待機と APC」を参照してください。

Objects パラメーターが指す配列は、非ページ システム メモリに存在する必要があります。 通常、ドライバーはローカル スタック上の Objects 配列にストレージを割り当てます。 Objects 配列は、WaitMode パラメーターの値に関係なく、ローカル スタックに割り当てられます。

Objects 配列内の要素が指すディスパッチャー オブジェクトは、非ページ システム メモリに存在する必要があります。 WaitMode パラメーターが UserMode の場合、待機中にカーネル スタックをスワップアウトできます。 したがって、呼び出し元は、UserMode 引数を指定して KeWaitForMultipleObjects を呼び出すときに、スタックにパラメーターを渡そうとしないでください。 スタックにイベントを割り当てる場合は、 WaitMode パラメーターを KernelMode に設定する必要があります。

KeWaitForMultipleObjects に渡される Object パラメーターがミューテックスである場合は、特別な考慮事項が適用されます。 待機しているディスパッチャー オブジェクトがミューテックスの場合、APC 配信は待機中の他のすべてのディスパッチャー オブジェクトの場合と同じです。 ただし、 KeWaitForMultipleObjects が STATUS_SUCCESS で戻り、スレッドが実際にミューテックスを保持した後は、特殊なカーネル モードの APC のみが配信されます。 カーネル モードとユーザー モードの両方の他のすべての APC の配信は無効になっています。 APC の配信に関するこの制限は、ミューテックスが解放されるまで保持されます。

WaitMode パラメーターが UserMode または AlertableTRUE の場合は、KeWaitForMultipleObjects の戻り値をチェックすることが特に重要です。KeWaitForMultipleObjects は、STATUS_USER_APCまたはSTATUS_ALERTEDの状態で早期に返される可能性があるためです。

ユーザーが中止できるすべての長期待機は UserMode 待機で、 AlertableFALSE に設定する必要があります。

可能な場合は、ドライバーの複雑さを軽減するために、 AlertableFALSE に設定し、 WaitModeKernelMode に設定する必要があります。 これに対する主な例外は、待機が長期待機である場合です。

ミューテックスは、MINLONG 回だけ再帰的に取得できます。 この制限を超えると、ルーチンによってSTATUS_MUTANT_LIMIT_EXCEEDED例外が発生します。

KeWaitForMultipleObjects の呼び出し元は、IRQL <= DISPATCH_LEVELで実行できます。 ただし、 Timeout = NULL または *Timeout != 0 の場合、呼び出し元は IRQL <= APC_LEVELおよび非arbitrary スレッド コンテキストで実行されている必要があります。 ( Timeout != NULL および *Timeout = 0 の場合、呼び出し元は IRQL <= DISPATCH_LEVEL で実行されている必要があります)。

要件

要件
サポートされている最小のクライアント Windows 2000 以降で使用できます。
対象プラットフォーム ユニバーサル
Header wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む)
Library NtosKrnl.lib
[DLL] NtosKrnl.exe
IRQL 「解説」を参照してください。
DDI コンプライアンス規則 HwStorPortProhibitedDDIs(storport)IrpProcessingComplete(wdm)IrqlKeWaitForMultipleObjects(wdm)SpNoWait(storport)

こちらもご覧ください

ExInitializeFastMutex

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForSingleObject