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
* 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

View file

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