Acquire always the apc lock if we are modifying the apc queue. Modified: trunk/reactos/ntoskrnl/ke/apc.c Modified: trunk/reactos/ntoskrnl/ke/process.c _____
Modified: trunk/reactos/ntoskrnl/ke/apc.c --- trunk/reactos/ntoskrnl/ke/apc.c 2005-07-26 19:15:08 UTC (rev 16753) +++ trunk/reactos/ntoskrnl/ke/apc.c 2005-07-26 19:21:27 UTC (rev 16754) @@ -245,7 +245,7 @@
* The APC will execute at APC_LEVEL for the KernelRoutine registered, and * at PASSIVE_LEVEL for the NormalRoutine registered. * - * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. + * Callers of this routine must have locked the dipatcher database. * *--*/ BOOLEAN @@ -257,9 +257,12 @@ PLIST_ENTRY ApcListEntry; PKAPC QueuedApc;
+ KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); + /* Don't do anything if the APC is already inserted */ if (Apc->Inserted) { - + + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); return FALSE; }
@@ -301,6 +304,8 @@ /* Confirm Insertion */ Apc->Inserted = TRUE;
+ KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); + /* * Three possibilites here again: * 1) Kernel APC, The thread is Running: Request an Interrupt @@ -318,13 +323,11 @@ #ifdef CONFIG_SMP PKPRCB Prcb, CurrentPrcb; LONG i; - KIRQL oldIrql; #endif
DPRINT ("Requesting APC Interrupt for Running Thread \n");
#ifdef CONFIG_SMP - oldIrql = KeRaiseIrqlToDpcLevel(); CurrentPrcb = KeGetCurrentPrcb(); if (CurrentPrcb->CurrentThread == Thread) { @@ -344,7 +347,6 @@ } ASSERT (i < KeNumberProcessors); } - KeLowerIrql(oldIrql); #else HalRequestSoftwareInterrupt(APC_LEVEL); #endif _____
Modified: trunk/reactos/ntoskrnl/ke/process.c --- trunk/reactos/ntoskrnl/ke/process.c 2005-07-26 19:15:08 UTC (rev 16753) +++ trunk/reactos/ntoskrnl/ke/process.c 2005-07-26 19:21:27 UTC (rev 16754) @@ -89,6 +89,7 @@
/* Initialize the Thread List */ InitializeListHead(&Process->ThreadListHead); + KeInitializeSpinLock(&Process->ProcessLock); DPRINT("The Process has now been initalized with the Kernel\n"); }
@@ -138,6 +139,7 @@
/* Lock Dispatcher */ OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */ if (KeIsExecutingDpc()) { @@ -150,6 +152,7 @@ if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
DPRINT("Process already Attached. Exitting\n"); + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); } else {
@@ -191,6 +194,7 @@ KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n"); @@ -232,6 +236,7 @@ UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */ if (KeIsExecutingDpc()) { @@ -273,6 +278,7 @@ /* Get Current Thread and Lock */ Thread = KeGetCurrentThread(); OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Check if it's attached */ DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex); @@ -297,6 +303,7 @@ KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Unlock Dispatcher */ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); }
@@ -320,6 +327,7 @@
Thread = KeGetCurrentThread(); OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */ if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) { @@ -347,6 +355,7 @@ KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Return to old IRQL*/ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); }