BOOLEAN
KeTestAlertThread (
__in KPROCESSOR_MODE AlertMode
)
/*++
Routine Description:
This function tests to determine if the alerted variable for the
specified processor mode has a value of TRUE or whether a user mode
APC should be delivered to the current thread.
Arguments:
AlertMode - Supplies the processor mode which is to be tested
for an alerted condition.
Return Value:
The previous state of the alerted variable for the specified processor
mode.
--*/
{
BOOLEAN Alerted;
KLOCK_QUEUE_HANDLE LockHandle;
PKTHREAD Thread;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Raise IRQL to SYNCH_LEVEL and acquire the thread APC queue lock.
//
Thread = KeGetCurrentThread();
KeAcquireInStackQueuedSpinLockRaiseToSynch(&Thread->ApcQueueLock,
&LockHandle);
//
// If the current thread is alerted for the specified processor mode,
// then clear the alerted state. Else if the specified processor mode
// is user and the current thread's user mode APC queue contains an
// entry, then set user APC pending.
//
Alerted = Thread->Alerted[AlertMode];
if (Alerted == TRUE) {
Thread->Alerted[AlertMode] = FALSE;
} else if ((AlertMode == UserMode) &&
(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) != TRUE)) {
Thread->ApcState.UserApcPending = TRUE;
}
//
// Release the thread APC queue lock, lower IRQL to its previous value,
// and return the previous alerted state for the specified mode.
//
KeReleaseInStackQueuedSpinLock(&LockHandle);
return Alerted;
}