Acquire always the apc lock if we are modifying the apc queue.
authorHartmut Birr <osexpert@googlemail.com>
Tue, 26 Jul 2005 19:21:27 +0000 (19:21 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Tue, 26 Jul 2005 19:21:27 +0000 (19:21 +0000)
svn path=/trunk/; revision=16754

reactos/ntoskrnl/ke/apc.c
reactos/ntoskrnl/ke/process.c

index bbb3728..5036825 100644 (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
index d6f6703..fbfdf3e 100644 (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);
 }