Friday, August 25, 2006 5:22 PM
doronh
A NULL and zero wait timeout are not the same
When you call
KeWaitForSingleObject or
KeWaitForMultipleObjects you can provide a pointer to a timeout value. What value you pass for the pointer value makes a huge difference. This subtle distinction is something that first time driver writers do not grasp and get wrong.
If you want to infinitely wait, you pass NULL for the timeout. You must be at IRQL == PASSIVE_LEVEL to infinitely wait.
If you want to perform a test and exit (e.g. do not wait all, just try to acquire the handle and return immediately), you pass a pointer which points to 0x0. You can be at IRQL <= DISPATCH_LEVEL if you want to perform the tes and exit. This allows you to optimize a code path at DISPATCH_LEVEL and then queue to PASSIVE_LEVEL on in the case where you cannot acquire the handle.
Here is a summary of the different waits (excluding absolute):
| Behavior |
Code |
| Infinitely wait |
KeWaitForSingleObject(<dispatcher object>,
Executive,
KernelMode,
FALSE,
NULL);
|
| Test and exit |
LARGE_INTEGER timeout;
timeout.QuadPart = 0x0;
KeWaitForSingleObject(<dispatcher object>,
Executive,
KernelMode,
FALSE,
&timeout); |
| Relative timeout of 500 ms |
LARGE_INTEGER timeout;
timeout.QuadPart = -5 * 10 // 100 ns to 1 us
* 1000 // us to ms
* 100; // 1ms to 100 ms
KeWaitForSingleObject(<dispatcher object>,
Executive,
KernelMode,
FALSE,
&timeout);
|