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