The KeWaitForSingleObject routine puts the current thread into a wait state until the given dispatcher object is set to a signaled state or (optionally) until the wait times out.
NTSTATUS
KeWaitForSingleObject(
IN PVOID Object,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL
);
KeWaitForSingleObject can return one of the following:
Note that the NT_SUCCESS macro recognizes all of these status values as "success" values.
Declared in wdm.h and ntddk.h. Include wdm.h or ntddk.h.
The current state of the specified Object is examined to determine whether the wait can be satisfied immediately. If so, the necessary side effects are performed on the object. Otherwise, the current thread is put in a waiting state and a new thread is selected for execution on the current processor.
The Alertable parameter specifies whether the thread can be alerted and its wait state consequently aborted. If the value of this parameter is FALSE then the thread cannot be alerted, no matter what the value of the WaitMode parameter or the origin of the alert. The only exception to this rule is that of a terminating thread. Under certain circumstances a terminating thread can be alerted while it is in the process of winding down. A thread is automatically made alertable, for instance, when terminated by a user with a CTRL+C.
If the value of Alertable is TRUE and one of the following conditions is present, the thread will be alerted:
In the first of these two cases, the thread’s wait is satisfied with a completion status of STATUS_ALERTED; in the second case, it is satisfied with a completion status of STATUS_USER_APC.
The thread must be alertable for a user-mode APC to be delivered. This is not the case for kernel-mode APCs. A kernel-mode APC can be delivered and executed even though the thread is not alerted. Once the APC's execution completes, the thread's wait resumes. A thread is never alerted, nor is its wait aborted, by the delivery of a kernel-mode APC.
The delivery of kernel-mode APCs to a waiting thread does not depend on whether the thread can be alerted. If the kernel-mode APC is a special kernel-mode APC, then the APC is delivered provided that IRQL < APC_LEVEL. If the kernel-mode APC is a normal kernel-mode APC, then the APC is delivered provided that the following three conditions hold: (1) IRQL < APC_LEVEL, (2) no kernel APC is in progress, and (3) the thread is not in a critical section.
A special consideration applies when the Object parameter passed to KeWaitForSingleObject is a mutex. If the dispatcher object waited on is a mutex, APC delivery is the same as for all other dispatcher objects during the wait. However, once KeWaitForSingleObject returns with STATUS_SUCCESS and the thread actually holds the mutex, only special kernel-mode APCs are delivered. Delivery of all other APCs, both kernel-mode and user-mode, is disabled. This restriction on the delivery of APCs persists until the mutex is released.
If the WaitMode parameter is UserMode, the kernel stack can be swapped out during the wait. Consequently, a caller must never attempt to pass parameters on the stack when calling KeWaitForSingleObject using the UserMode argument. If you allocate the event on the stack, you must set the WaitMode parameter to KernelMode.
It is especially important to check the return value of KeWaitForSingleObject when the WaitMode parameter is UserMode or Alertable is TRUE, because KeWaitForSingleObject might return early with a status of STATUS_USER_APC or STATUS_ALERTED.
All long term waits that can be aborted by a user should be UserMode waits and Alertable should be set to FALSE.
Where possible, Alertable should be set to FALSE and WaitMode should be set to KernelMode, in order to reduce driver complexity. The principal exception to this is when the wait is a long term wait.
For additional information, see Do Waiting Threads Receive Alerts and APCs?
If no Timeout is supplied, the calling thread remains in a wait state until the Object is signaled.
A Timeout of zero allows the testing of a set of wait conditions and for the conditional performance of any side effects if the wait can be immediately satisfied, as in the acquisition of a mutex.
Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. Usually, the caller must be running at IRQL = PASSIVE_LEVEL and in a nonarbitrary thread context. A call while running at IRQL = DISPATCH_LEVEL is valid if and only if the caller specifies a Timeout of zero. That is, a driver must not wait for a nonzero interval at IRQL = DISPATCH_LEVEL.
ExInitializeFastMutex, KeBugCheckEx, KeInitializeEvent, KeInitializeMutex, KeInitializeSemaphore, KeInitializeTimer, KeWaitForMultipleObjects, KeWaitForMutexObject