diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index bbb372810dd..5036825ca29 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -245,7 +245,7 @@ KeInitializeApc(IN PKAPC Apc, * 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 @@ KiInsertQueueApc(PKAPC Apc, 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 @@ KiInsertQueueApc(PKAPC Apc, /* 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 @@ KiInsertQueueApc(PKAPC Apc, #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 @@ KiInsertQueueApc(PKAPC Apc, } ASSERT (i < KeNumberProcessors); } - KeLowerIrql(oldIrql); #else HalRequestSoftwareInterrupt(APC_LEVEL); #endif diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index d6f67031577..fbfdf3e774c 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -89,6 +89,7 @@ KeInitializeProcess(PKPROCESS Process, /* 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 @@ KeAttachProcess(PKPROCESS Process) /* Lock Dispatcher */ OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); /* Crash system if DPC is being executed! */ if (KeIsExecutingDpc()) { @@ -150,6 +152,7 @@ KeAttachProcess(PKPROCESS Process) if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) { DPRINT("Process already Attached. Exitting\n"); + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); } else { @@ -191,6 +194,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE KiSwapProcess(Process, SavedApcState->Process); /* Return to old IRQL*/ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(ApcLock); DPRINT("KiAttachProcess Completed Sucesfully\n"); @@ -232,6 +236,7 @@ KeStackAttachProcess(IN PKPROCESS Process, UpdatePageDirs(Thread, Process); OldIrql = KeAcquireDispatcherDatabaseLock(); + KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); /* Crash system if DPC is being executed! */ if (KeIsExecutingDpc()) { @@ -273,6 +278,7 @@ KeDetachProcess (VOID) /* 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 @@ KeDetachProcess (VOID) KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); /* Unlock Dispatcher */ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); } @@ -320,6 +327,7 @@ KeUnstackDetachProcess ( 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 @@ KeUnstackDetachProcess ( KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); /* Return to old IRQL*/ + KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); KeReleaseDispatcherDatabaseLock(OldIrql); }