diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index ec6fcf015ab..3e34445d147 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -469,29 +469,23 @@ KeFlushQueueApc(IN PKTHREAD Thread, { KIRQL OldIrql; PKAPC Apc; - PLIST_ENTRY ApcEntry, CurrentEntry; + PLIST_ENTRY FirstEntry, CurrentEntry; /* Lock the Dispatcher Database and APC Queue */ OldIrql = KeAcquireDispatcherDatabaseLock(); KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); - ApcEntry = CurrentEntry = NULL; - while (!IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) - { - if (ApcEntry == NULL) - { - ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]); - } - else - { - CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]); - CurrentEntry = CurrentEntry->Flink; - } - CurrentEntry->Flink = NULL; - - /* Get the APC */ - Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); - Apc->Inserted = FALSE; + if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { + FirstEntry = NULL; + } else { + FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink; + RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]); + CurrentEntry = FirstEntry; + do { + Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); + Apc->Inserted = FALSE; + CurrentEntry = CurrentEntry->Flink; + } while (CurrentEntry != FirstEntry); } /* Release the locks */ @@ -499,7 +493,7 @@ KeFlushQueueApc(IN PKTHREAD Thread, KeReleaseDispatcherDatabaseLock(OldIrql); /* Return the first entry */ - return ApcEntry; + return FirstEntry; } /*++ diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index be6a46e5534..c3ea033e7c1 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -214,7 +214,7 @@ PspExitThread(NTSTATUS ExitStatus) PTERMINATION_PORT TerminationPort; PTEB Teb; KIRQL oldIrql; - PLIST_ENTRY ApcEntry; + PLIST_ENTRY FirstEntry, CurrentEntry; PKAPC Apc; DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread()); @@ -340,37 +340,42 @@ PspExitThread(NTSTATUS ExitStatus) KeDisableThreadApcQueueing(&CurrentThread->Tcb); /* Flush the User APCs */ - ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode); - while(ApcEntry) + FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode); + if (FirstEntry != NULL) { - /* Get the APC */ - Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry); + CurrentEntry = FirstEntry; + do + { + /* Get the APC */ + Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); - /* Move to the next one */ - ApcEntry = ApcEntry->Flink; + /* Move to the next one */ + CurrentEntry = CurrentEntry->Flink; - /* Rundown the APC or de-allocate it */ - if (Apc->RundownRoutine) - { - /* Call its own routine */ - (Apc->RundownRoutine)(Apc); - } - else - { - /* Do it ourselves */ - ExFreePool(Apc); - } + /* Rundown the APC or de-allocate it */ + if (Apc->RundownRoutine) + { + /* Call its own routine */ + (Apc->RundownRoutine)(Apc); + } + else + { + /* Do it ourselves */ + ExFreePool(Apc); + } + } + while (CurrentEntry != FirstEntry); } /* Call the Lego routine */ if (CurrentThread->Tcb.LegoData) PspRunLegoRoutine(&CurrentThread->Tcb); /* Flush the APC queue, which should be empty */ - if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode))) + if ((FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode))) { /* Bugcheck time */ KEBUGCHECKEX(KERNEL_APC_PENDING_DURING_EXIT, - (ULONG_PTR)ApcEntry, + (ULONG_PTR)FirstEntry, CurrentThread->Tcb.KernelApcDisable, oldIrql, 0);