FsRtlCancellableWaitForMultipleObjects 函式 (ntifs.h)

FsRtlCancellableWaitForMultipleObjects 例程會執行可取消的等候作業, (可在一或多個發送器對象上終止) 。

語法

NTSTATUS FsRtlCancellableWaitForMultipleObjects(
  [in]           ULONG          Count,
  [in]           PVOID []       ObjectArray,
  [in]           WAIT_TYPE      WaitType,
  [in, optional] PLARGE_INTEGER Timeout,
  [in, optional] PKWAIT_BLOCK   WaitBlockArray,
  [in, optional] PIRP           Irp
);

參數

[in] Count

要等候的物件數目。

[in] ObjectArray

發送器物件的指標陣列指標, (事件、Mutex、號誌、線程和定時器) ,呼叫端會為其提供記憶體。

[in] WaitType

WaitAll,這表示所有指定的對象都必須在滿足等候之前取得訊號狀態;或 WaitAny,表示任何一個對象都必須取得訊號狀態,才能滿足等候。

[in, optional] Timeout

選擇性逾時值的指標。 此參數會以 100 奈秒的單位指定絕對或相對時間,等候完成。

如果 Timeout 指向零值 (即 *Timeout == 0) ,則例程會傳回而不等候。 如果呼叫端 (提供 NULL 指標,也就是 Timeout == NULL) ,則例程會無限期等候,直到任何或所有發送器物件都設定為訊號狀態為止。

正值指定相對於 1601 年 1 月 1 日的絕對時間。 負值會指定相對於目前時間的間隔。 絕對到期時間會追蹤系統時間中的任何變更;相對到期時間不會受到系統時間變更的影響。

如果指定 Timeout ,當指定的間隔到期時,如果不符合任何指定的等候條件,就會自動滿足等候。

零 (逾時值,也就是 *Timeout == 0) 可讓您測試一組等候條件,並在等候可立即滿足時有條件地執行任何其他動作,如同取得 mutex 一樣。

[in, optional] WaitBlockArray

如果 Count<= THREAD_WAIT_OBJECTS,WaitBlockArray 可以是 NULL。 否則,此參數必須指向位元組的 sizeof(KWAIT_BLOCK * Count) 記憶體緩衝區。 此例程會在執行等候作業時使用此緩衝區進行記錄保留。

[in, optional] Irp

與使用者發出且可由使用者取消之 I/O 作業相對應之原始 IRP 的指標。 呼叫端必須確定 IRP 在這段例程期間仍有效,而且 IRP 不能有取消例程集 (例如 ,IoSetCancelRoutine 不得在 IRP) 上呼叫。 請注意,呼叫端必須持有 IRP,它無法傳遞至較低層級的驅動程式。

傳回值

FsRtlCancellableWaitForMultipleObjects 可以傳回下列其中一個值:

傳回碼 Description
STATUS_SUCCESS 呼叫端為 WaitType 參數指定 WaitAll ,而 ObjectArray 陣列中的所有發送器物件都已設定為已發出訊號的狀態。
STATUS_TIMEOUT 在符合指定的等候條件集之前發生逾時。 當指定的等候條件集無法立即符合且 Timeout 設定為零時,可以傳回此值。
透過 STATUS_WAIT_63 STATUS_WAIT_0 呼叫端為 WaitType 指定 WaitAny,而 ObjectArray 陣列中的其中一個發送器物件已設定為已發出訊號的狀態。 傳回值的下六位會編碼滿足等候之物件之以零起始的索引。
透過 STATUS_ABANDONED_WAIT_63 STATUS_ABANDONED_WAIT_0 呼叫端嘗試等候已放棄的 Mutex。 傳回值的下六位會編碼 ObjectArray 陣列中 Mutex 之以零起始的索引。
STATUS_CANCELLED 等候因指定 IRP 上的擱置取消要求而中斷。 請注意,只有在有效的 IRP 傳遞至 FsRtlCancellableWaitForMultipleObjectsCancelSynchronousIo 取消 IRP 時,才會傳回此值。
STATUS_THREAD_IS_TERMINATING 等候已中斷,因為線程已由應用程式或用戶終止。

傳回值只會指出等候的狀態。 如果適用,應該直接從處理原始使用者模式 IRP 的過程中所產生的另一個 IRP 取得 I/O 要求的實際狀態。

請注意,NT_SUCCESS宏會針對 STATUS_CANCELLED其他所有狀態值傳回 FALSE (“failure”) ,STATUS_THREAD_IS_TERMINATING狀態值和 TRUE (“success”) 。

備註

FsRtlCancellableWaitForMultipleObjects 例程會在發送器對象上執行可取消的等候作業。 如果使用者或應用程式終止線程,或 CancelSynchronousIo 在線程的 IRP 上張貼取消要求, (與線程相關聯的同步 IRP) ,則會取消等候。

FsRtlCancellableWaitForMultipleObjects 例程的設計目的是為了支援從 Windows Vista 開始的 I/O 完成/取消指導方針。 這些指導方針的目標是允許使用者 (或應用程式) 快速終止應用程式。 接著,這需要應用程式能夠快速終止執行 I/O 的線程,以及任何目前的 I/O 作業。 此例程提供一種方式,讓使用者線程封鎖 (,也就是說,等候核心中的) I/O 完成、發送器物件或同步處理變數,以允許立即取消等候。 如果線程由使用者或應用程式終止,此例程也允許線程的等候終止。

例如,重新導向器可能需要建立一或多個次要 IRP,才能處理使用者模式 IRP,並同步等候次要 IRP 完成。 其中一個做法是設定事件,該事件將由次要 IRP 的完成例程發出訊號,然後等候事件收到訊號。 然後,若要執行可取消的等候作業,則會呼叫 FsRtlCancellableWaitForMultipleObjects 傳入與次要 IRP 相關聯的事件,以及原始的使用者模式 IRP。 如果發生擱置終止事件或原始使用者模式 IRP 已取消,線程等候事件發出訊號就會取消。

請注意,終止等候不會自動取消呼叫端所發出的任何 I/O 作業, 必須由呼叫端個別處理。

每個線程物件都有一個內建的等候區塊陣列,可用來同時等候數個物件。 可能的話,等候區塊的內建數位應該用於等候多重作業中,因為不需要配置額外的等候區塊記憶體,之後再解除分配。 不過,如果必須同時等候的物件數目大於內建等候區塊的數目,請使用 WaitBlockArray 參數來指定等候作業中要使用的替代等候區塊集。 驅動程式只需要為 WaitBlockArray 配置足夠大型的記憶體緩衝區。 緩衝區不需要初始化,而且驅動程式可以將它視為不透明結構。 一旦例程傳回,就可以釋放緩衝區。

如果 Count 大於 MAXIMUM_WAIT_OBJECTS,或者 WaitBlockArray 為 NULL 且 Count 大於 THREAD_WAIT_OBJECTS,則系統會發出 錯誤檢查0xC:MAXIMUM_WAIT_OBJECTS_EXCEEDED

當傳遞至 FsRtlCancellableWaitForMultipleObjectsObjectArray 參數是 mutex 時,適用特殊考慮。 如果等候的發送器對像是 mutex,則 APC 傳遞與等候期間所有其他發送器物件相同。 不過,一旦 FsRtlCancellableWaitForMultipleObjects 傳回STATUS_SUCCESS,且線程實際上會保存 mutex,只會傳遞特殊的內核模式 APC。 已停用核心模式和使用者模式的所有其他 APC 傳遞。 在釋放 mutex 之前,傳遞 APC 的限制會持續存在。

Mutex 只能以遞歸方式取得MINLONG時間。 如果超過此限制,例程會引發STATUS_MUTANT_LIMIT_EXCEEDED例外狀況。

如果選用的 Irp 參數指向有效的 IRP,則必須在 IRQL PASSIVE_LEVEL呼叫 FsRtlCancellableWaitForMultipleObjects。 如果未使用 Irp 參數,可以在 IRQL 中呼叫例程小於或等於APC_LEVEL。 呼叫者可以視需要呼叫 KeEnterCriticalRegionFsRtlEnterFileSystem 例程來停用一般核心 APC。 不過,不得停用特殊核心 APC。

如果 IRQL 大於或等於APC_LEVEL且 Irp 參數指向有效的 IRP,FsRtlCancellableWaitForMultipleObjects 會在偵錯組建上判斷提示。

規格需求

需求
最低支援的用戶端 Windows Vista
目標平台 Universal
標頭 ntifs.h (包含 Ntifs.h)
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL 請參閱一節。
DDI 合規性規則 HwStorPortProhibitedDDIs (storport) PowerIrpDDis (wdm) SpNoWait (storport)

另請參閱

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject