KiActivateWaiterQueue函数和Queue->Header.WaitListHead队列等待列表的关系

第一部分:

if (Thread->ApcState.KernelApcPending &&

(Thread->SpecialApcDisable == 0) &&

(Thread->WaitIrql < APC_LEVEL)) {

} else {

//

// Insert wait block in object wait list.

//

InsertTailList(&Queue->Header.WaitListHead, &WaitBlock->WaitListEntry);

VOID

FORCEINLINE

InsertTailList(

IN PLIST_ENTRY ListHead,

IN PLIST_ENTRY Entry

)

{

PLIST_ENTRY Blink;

Blink = ListHead->Blink;

Entry->Flink = ListHead;

Entry->Blink = Blink;

Blink->Flink = Entry;

ListHead->Blink = Entry;

}

//LIFO队列

第二部分:

NTSTATUS

KeDelayExecutionThread (

IN KPROCESSOR_MODE WaitMode,

IN BOOLEAN Alertable,

IN PLARGE_INTEGER Interval

)

{

//

// If the current thread is processing a queue entry, then attempt

// to activate another thread that is blocked on the queue object.

//

Queue = Thread->Queue;

if (Queue != NULL) {

KiActivateWaiterQueue(Queue);

}

NTSTATUS

KeWaitForMultipleObjects (

IN ULONG Count,

IN PVOID Object[],

IN WAIT_TYPE WaitType,

IN KWAIT_REASON WaitReason,

IN KPROCESSOR_MODE WaitMode,

IN BOOLEAN Alertable,

IN PLARGE_INTEGER Timeout OPTIONAL,

IN PKWAIT_BLOCK WaitBlockArray OPTIONAL

)

{

//

// If the current thread is processing a queue entry, then attempt

// to activate another thread that is blocked on the queue object.

//

Queue = Thread->Queue;

if (Queue != NULL) {

KiActivateWaiterQueue(Queue);

}

NTSTATUS

KeWaitForSingleObject (

IN PVOID Object,

IN KWAIT_REASON WaitReason,

IN KPROCESSOR_MODE WaitMode,

IN BOOLEAN Alertable,

IN PLARGE_INTEGER Timeout OPTIONAL

)

{

//

// If the current thread is processing a queue entry, then attempt

// to activate another thread that is blocked on the queue object.

//

Queue = Thread->Queue;

if (Queue != NULL) {

KiActivateWaiterQueue(Queue);

}

第三部分:

FORCEINLINE

VOID

KiActivateWaiterQueue (

IN PRKQUEUE Queue

)

/*++

Routine Description:

This function is called when the current thread is about to enter a

wait state and is currently processing a queue entry. The current

number of threads processign entries for the queue is decrement and

an attempt is made to activate another thread if the current count

is less than the maximum count, there is a waiting thread, and the

queue is not empty.

N.B. It is possible that this function is called on one processor

holding the dispatcher database lock while the state of the

specified queue object is being modified on another processor

while holding only the queue object lock. This does not cause

a problem since holding the queue object lock ensures that

there are no waiting threads.

Arguments:

Queue - Supplies a pointer to a dispatcher object of type event.

Return Value:

None.

--*/

{

PRLIST_ENTRY Entry;

PRKTHREAD Thread;

PRKWAIT_BLOCK WaitBlock;

PRLIST_ENTRY WaitEntry;

//

// Decrement the current count of active threads and check if another

// thread can be activated. If the current number of active threads is

// less than the target maximum number of threads, there is a entry in

// in the queue, and a thread is waiting, then remove the entry from the

// queue, decrement the number of entries in the queue, and unwait the

// respectiive thread.

//

Queue->CurrentCount -= 1;

if (Queue->CurrentCount < Queue->MaximumCount) {

Entry = Queue->EntryListHead.Flink;

WaitEntry = Queue->Header.WaitListHead.Blink;//LIFO队列

if ((Entry != &Queue->EntryListHead) &&

(WaitEntry != &Queue->Header.WaitListHead)) {

RemoveEntryList(Entry);

Entry->Flink = NULL;

Queue->Header.SignalState -= 1;

WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);

Thread = WaitBlock->Thread;

KiUnwaitThread(Thread, (LONG_PTR)Entry, 0);

}

}

return;

}

相关推荐
sitelist19 天前
_DISPATCHER_HEADER结构中的WaitListHead和_KWAIT_BLOCK的关系
dispatcher_hea·atcher_header·waitlisthead·kwait_block·kesetevent