- 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);