Acquire always the apc lock if we are modifying the apc queue.

svn path=/trunk/; revision=16754
This commit is contained in:
Hartmut Birr 2005-07-26 19:21:27 +00:00
parent ec8a1499ee
commit dd90242aa7
2 changed files with 16 additions and 5 deletions

View file

@ -245,7 +245,7 @@ KeInitializeApc(IN PKAPC Apc,
* The APC will execute at APC_LEVEL for the KernelRoutine registered, and * The APC will execute at APC_LEVEL for the KernelRoutine registered, and
* at PASSIVE_LEVEL for the NormalRoutine registered. * 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 BOOLEAN
@ -257,9 +257,12 @@ KiInsertQueueApc(PKAPC Apc,
PLIST_ENTRY ApcListEntry; PLIST_ENTRY ApcListEntry;
PKAPC QueuedApc; PKAPC QueuedApc;
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Don't do anything if the APC is already inserted */ /* Don't do anything if the APC is already inserted */
if (Apc->Inserted) { if (Apc->Inserted) {
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
return FALSE; return FALSE;
} }
@ -301,6 +304,8 @@ KiInsertQueueApc(PKAPC Apc,
/* Confirm Insertion */ /* Confirm Insertion */
Apc->Inserted = TRUE; Apc->Inserted = TRUE;
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
/* /*
* Three possibilites here again: * Three possibilites here again:
* 1) Kernel APC, The thread is Running: Request an Interrupt * 1) Kernel APC, The thread is Running: Request an Interrupt
@ -318,13 +323,11 @@ KiInsertQueueApc(PKAPC Apc,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
PKPRCB Prcb, CurrentPrcb; PKPRCB Prcb, CurrentPrcb;
LONG i; LONG i;
KIRQL oldIrql;
#endif #endif
DPRINT ("Requesting APC Interrupt for Running Thread \n"); DPRINT ("Requesting APC Interrupt for Running Thread \n");
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
oldIrql = KeRaiseIrqlToDpcLevel();
CurrentPrcb = KeGetCurrentPrcb(); CurrentPrcb = KeGetCurrentPrcb();
if (CurrentPrcb->CurrentThread == Thread) if (CurrentPrcb->CurrentThread == Thread)
{ {
@ -344,7 +347,6 @@ KiInsertQueueApc(PKAPC Apc,
} }
ASSERT (i < KeNumberProcessors); ASSERT (i < KeNumberProcessors);
} }
KeLowerIrql(oldIrql);
#else #else
HalRequestSoftwareInterrupt(APC_LEVEL); HalRequestSoftwareInterrupt(APC_LEVEL);
#endif #endif

View file

@ -89,6 +89,7 @@ KeInitializeProcess(PKPROCESS Process,
/* Initialize the Thread List */ /* Initialize the Thread List */
InitializeListHead(&Process->ThreadListHead); InitializeListHead(&Process->ThreadListHead);
KeInitializeSpinLock(&Process->ProcessLock);
DPRINT("The Process has now been initalized with the Kernel\n"); DPRINT("The Process has now been initalized with the Kernel\n");
} }
@ -138,6 +139,7 @@ KeAttachProcess(PKPROCESS Process)
/* Lock Dispatcher */ /* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */ /* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) { if (KeIsExecutingDpc()) {
@ -150,6 +152,7 @@ KeAttachProcess(PKPROCESS Process)
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) { if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
DPRINT("Process already Attached. Exitting\n"); DPRINT("Process already Attached. Exitting\n");
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql); KeReleaseDispatcherDatabaseLock(OldIrql);
} else { } else {
@ -191,6 +194,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE
KiSwapProcess(Process, SavedApcState->Process); KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/ /* Return to old IRQL*/
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(ApcLock); KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n"); DPRINT("KiAttachProcess Completed Sucesfully\n");
@ -232,6 +236,7 @@ KeStackAttachProcess(IN PKPROCESS Process,
UpdatePageDirs(Thread, Process); UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Crash system if DPC is being executed! */ /* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) { if (KeIsExecutingDpc()) {
@ -273,6 +278,7 @@ KeDetachProcess (VOID)
/* Get Current Thread and Lock */ /* Get Current Thread and Lock */
Thread = KeGetCurrentThread(); Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Check if it's attached */ /* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex); DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
@ -297,6 +303,7 @@ KeDetachProcess (VOID)
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Unlock Dispatcher */ /* Unlock Dispatcher */
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql); KeReleaseDispatcherDatabaseLock(OldIrql);
} }
@ -320,6 +327,7 @@ KeUnstackDetachProcess (
Thread = KeGetCurrentThread(); Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */ /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) { if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
@ -347,6 +355,7 @@ KeUnstackDetachProcess (
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Return to old IRQL*/ /* Return to old IRQL*/
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql); KeReleaseDispatcherDatabaseLock(OldIrql);
} }