- Fixed the broken implementation of KeFlushQueueApc. - Fixed some locking operations with two spin locks. Modified: trunk/reactos/ntoskrnl/ke/apc.c Modified: trunk/reactos/ntoskrnl/ps/kill.c _____
Modified: trunk/reactos/ntoskrnl/ke/apc.c --- trunk/reactos/ntoskrnl/ke/apc.c 2005-07-26 19:02:31 UTC (rev 16751) +++ trunk/reactos/ntoskrnl/ke/apc.c 2005-07-26 19:11:25 UTC (rev 16752) @@ -270,14 +270,14 @@
*/ if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
- DPRINT1("Inserting the Process Exit APC into the Queue\n"); + DPRINT1("Inserting the Thread Exit APC for '%.16s' into the Queue\n", ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcLis tHead[(int)Apc->ApcMode], &Apc->ApcListEntry);
} else if (Apc->NormalRoutine == NULL) {
- DPRINT("Inserting Special APC %x into the Queue\n", Apc); + DPRINT("Inserting Special APC %x for '%.16s' into the Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc-> ApcMode].Flink; ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc-
ApcMode];
@@ -293,7 +293,7 @@
} else {
- DPRINT("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode); + DPRINT("Inserting Normal APC %x for '%.16s' into the %x Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName, Apc->ApcMode);
InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcLis tHead[(int)Apc->ApcMode], &Apc->ApcListEntry); } @@ -473,34 +473,27 @@ OldIrql = KeAcquireDispatcherDatabaseLock(); KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
- /* Check if the list is empty */ - if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) + ApcEntry = CurrentEntry = NULL; + while (!IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { - /* We'll return NULL */ - ApcEntry = NULL; - } - else - { - /* Remove this one */ - RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]); - CurrentEntry = ApcEntry; + if (ApcEntry == NULL) + { + ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]); + } + else + { + CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]); + CurrentEntry = CurrentEntry->Flink; + } + CurrentEntry->Flink = NULL;
- /* Remove all the other ones too, if present */ - do - { - /* Get the APC */ - Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); - - /* Move to the next one */ - CurrentEntry = CurrentEntry->Flink; - - /* Mark it as not inserted */ - Apc->Inserted = FALSE; - } while (ApcEntry != CurrentEntry); + /* Get the APC */ + Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); + Apc->Inserted = FALSE; }
/* Release the locks */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql);
/* Return the first entry */ @@ -539,7 +532,7 @@ DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
OldIrql = KeAcquireDispatcherDatabaseLock(); - KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Check if it's inserted */ if (Apc->Inserted) { @@ -565,13 +558,13 @@ } else {
/* It's not inserted, fail */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); return(FALSE); }
/* Restore IRQL and Return */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); return(TRUE); } _____
Modified: trunk/reactos/ntoskrnl/ps/kill.c --- trunk/reactos/ntoskrnl/ps/kill.c 2005-07-26 19:02:31 UTC (rev 16751) +++ trunk/reactos/ntoskrnl/ps/kill.c 2005-07-26 19:11:25 UTC (rev 16752) @@ -213,7 +213,7 @@
PTERMINATION_PORT TerminationPort; PTEB Teb; KIRQL oldIrql; - PLIST_ENTRY ApcEntry, CurrentApc; + PLIST_ENTRY ApcEntry; PKAPC Apc;
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread()); @@ -338,30 +338,26 @@ KeDisableThreadApcQueueing(&CurrentThread->Tcb);
/* Flush the User APCs */ - if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode))) + ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode); + while(ApcEntry) { - CurrentApc = ApcEntry; - do - { - /* Get the APC */ - Apc = CONTAINING_RECORD(CurrentApc, KAPC, ApcListEntry); + /* Get the APC */ + Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
- /* Move to the next one */ - CurrentApc = CurrentApc->Flink; + /* Move to the next one */ + ApcEntry = ApcEntry->Flink;
- /* Rundown the APC or de-allocate it */ - if (Apc->RundownRoutine) - { - /* Call its own routine */ - (Apc->RundownRoutine)(Apc); - } - else - { - /* Do it ourselves */ - ExFreePool(Apc); - } - } - while (CurrentApc != ApcEntry); + /* Rundown the APC or de-allocate it */ + if (Apc->RundownRoutine) + { + /* Call its own routine */ + (Apc->RundownRoutine)(Apc); + } + else + { + /* Do it ourselves */ + ExFreePool(Apc); + } }
/* Call the Lego routine */ @@ -392,8 +388,8 @@ PVOID* SystemArgument1, PVOID* SystemArguemnt2) { - DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n", - PsGetCurrentThread(), PsGetCurrentProcess()); + DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x, '%.16s')\n", + PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
/* Don't do anything unless we are in User-Mode */ if (Apc->SystemArgument2) @@ -421,8 +417,8 @@ PETHREAD Thread = PsGetCurrentThread(); NTSTATUS ExitStatus;
- DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x)\n", - PsGetCurrentThread(), PsGetCurrentProcess()); + DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x, '%.16s')\n", + PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
/* This should never happen */ ASSERT(!SystemArgument2);