> 1. What on the earth is the “alertable state” of thread? Its
characteristics ?
This means that KeWaitForSingleObject can be interrupted by thread
alertion, which is usually the case when an APC is delivered for a
thread.
In this case, KeWaitForSingleObject returns STATUS_ALERTED or
STATUS_USER_APC, and you must be prepared to handle this - usually by
returning from your driver ASAP.
- What is the mechanism of APC in kernel ?
There are 3 kinds of APCs - user APCs queued by QueueUserApc, kernel
APCs, and “special kernel APC” which is IIRC IopCompleteRequest only.
Process and thread termination and suspend are also delivered as
user APCs, though they execute in kernel mode.
User APC is executed on returning from kernel mode to user mode, one
by one. Since the system thread cannot do this, and thread termination
or suspend is a user APC, the system thread cannot be terminated
externally and cannot be suspended.
After the user-mode routine for a user APC is called by
ntdll!KiUserApcDispatcher, KiUserApcDispatcher calls the NtContinue
syscall which continues the user APC queue unwind. After the queue is
done, the usual thread execution is resumed.
Kernel APC is executed at the first moment after it is scheduled,
provided the IRQL is PASSIVE_LEVEL and KeEnterCriticalRegion was not
called.
Special kernel APC - IopCompleteRequest - is executed at the first
moment after it is scheduled, provided the IRQL is PASSIVE_LEVEL.
KeEnterCriticalRegion does not block special kernel APCs, only raising
to APC_LEVEL does.
Fast mutex raises to APC_LEVEL (unless the xxxUnsafe function is
called), thus blocking all APCs. This means that Irp->UserEvent will
not be signaled, since it is signaled by IopCompleteRequest APC. So,
you cannot call ZwxxxFile function and wait on the event specified to
it on APC_LEVEL, which is turn means that you must not call ZwxxxFile
on APC_LEVEL.
As about whether the APC queueing to the thread will interrupt
KeWaitForxxx - it depends on Alertable and ProcessorMode parameters to
KeWaitForxxx. This is documented on MSDN.
Max