- Fixed the broken implementation of KeFlushQueueApc.
authorHartmut Birr <osexpert@googlemail.com>
Tue, 26 Jul 2005 19:11:25 +0000 (19:11 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Tue, 26 Jul 2005 19:11:25 +0000 (19:11 +0000)
- Fixed some locking operations with two spin locks.

svn path=/trunk/; revision=16752

reactos/ntoskrnl/ke/apc.c
reactos/ntoskrnl/ps/kill.c

index c8c4847..b236385 100644 (file)
@@ -270,14 +270,14 @@ KiInsertQueueApc(PKAPC Apc,
     */
     if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
 
-        DPRINT1("Inserting the Process Exit APC into the Queue\n");
+        DPRINT1("Inserting the Thread Exit APC for '%.16s' into the Queue\n", ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
         Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
         InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
                        &Apc->ApcListEntry);
 
     } else if (Apc->NormalRoutine == NULL) {
 
-        DPRINT("Inserting Special APC %x into the Queue\n", Apc);
+        DPRINT("Inserting Special APC %x for '%.16s' into the Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
 
         for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
              ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
@@ -293,7 +293,7 @@ KiInsertQueueApc(PKAPC Apc,
 
     } else {
 
-        DPRINT("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
+        DPRINT("Inserting Normal APC %x for '%.16s' into the %x Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName, Apc->ApcMode);
         InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
                        &Apc->ApcListEntry);
     }
@@ -473,34 +473,27 @@ KeFlushQueueApc(IN PKTHREAD Thread,
     OldIrql = KeAcquireDispatcherDatabaseLock();
     KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
 
-    /* Check if the list is empty */
-    if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode]))
+    ApcEntry = CurrentEntry = NULL;
+    while (!IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode]))
     {
-        /* We'll return NULL */
-        ApcEntry = NULL;
-    }
-    else
-    {
-        /* Remove this one */
-        RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]);
-        CurrentEntry = ApcEntry;
-
-        /* Remove all the other ones too, if present */
-        do
-        {
-            /* Get the APC */
-            Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
-
-            /* Move to the next one */
-            CurrentEntry = CurrentEntry->Flink;
-
-            /* Mark it as not inserted */
-            Apc->Inserted = FALSE;
-        } while (ApcEntry != CurrentEntry);
+       if (ApcEntry == NULL)
+       {
+          ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
+       }
+       else
+       {
+          CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
+          CurrentEntry = CurrentEntry->Flink;
+       }
+       CurrentEntry->Flink = NULL;
+
+       /* Get the APC */
+       Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
+       Apc->Inserted = FALSE;
     }
 
     /* Release the locks */
-    KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
     KeReleaseDispatcherDatabaseLock(OldIrql);
 
     /* Return the first entry */
@@ -539,7 +532,7 @@ KeRemoveQueueApc(PKAPC Apc)
     DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
 
     OldIrql = KeAcquireDispatcherDatabaseLock();
-    KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+    KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
 
     /* Check if it's inserted */
     if (Apc->Inserted) {
@@ -565,13 +558,13 @@ KeRemoveQueueApc(PKAPC Apc)
     } else {
 
         /* It's not inserted, fail */
-        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+        KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
         KeReleaseDispatcherDatabaseLock(OldIrql);
         return(FALSE);
     }
 
     /* Restore IRQL and Return */
-    KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
     KeReleaseDispatcherDatabaseLock(OldIrql);
     return(TRUE);
 }
index 2bb45c6..42f5554 100644 (file)
@@ -213,7 +213,7 @@ PspExitThread(NTSTATUS ExitStatus)
     PTERMINATION_PORT TerminationPort;
     PTEB Teb;
     KIRQL oldIrql;
-    PLIST_ENTRY ApcEntry, CurrentApc;
+    PLIST_ENTRY ApcEntry;
     PKAPC Apc;
 
     DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
@@ -338,30 +338,26 @@ PspExitThread(NTSTATUS ExitStatus)
     KeDisableThreadApcQueueing(&CurrentThread->Tcb);
 
     /* Flush the User APCs */
-    if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode)))
+    ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
+    while(ApcEntry)
     {
-        CurrentApc = ApcEntry;
-        do
-        {
-            /* Get the APC */
-            Apc = CONTAINING_RECORD(CurrentApc, KAPC, ApcListEntry);
-
-            /* Move to the next one */
-            CurrentApc = CurrentApc->Flink;
-
-            /* Rundown the APC or de-allocate it */
-            if (Apc->RundownRoutine)
-            {
-                /* Call its own routine */
-                (Apc->RundownRoutine)(Apc);
-            }
-            else
-            {
-                /* Do it ourselves */
-                ExFreePool(Apc);
-            }
-        }
-        while (CurrentApc != ApcEntry);
+       /* Get the APC */
+       Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
+
+       /* Move to the next one */
+       ApcEntry = ApcEntry->Flink;
+
+       /* Rundown the APC or de-allocate it */
+       if (Apc->RundownRoutine)
+       {
+          /* Call its own routine */
+          (Apc->RundownRoutine)(Apc);
+       }
+       else
+       {
+          /* Do it ourselves */
+          ExFreePool(Apc);
+       }
     }
 
     /* Call the Lego routine */
@@ -392,8 +388,8 @@ PsExitSpecialApc(PKAPC Apc,
                  PVOID* SystemArgument1,
                  PVOID* SystemArguemnt2)
 {
-    DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n", 
-            PsGetCurrentThread(), PsGetCurrentProcess());
+    DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
+            PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
 
     /* Don't do anything unless we are in User-Mode */
     if (Apc->SystemArgument2)
@@ -421,8 +417,8 @@ PspExitNormalApc(PVOID NormalContext,
     PETHREAD Thread = PsGetCurrentThread();
     NTSTATUS ExitStatus;
         
-    DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x)\n", 
-            PsGetCurrentThread(), PsGetCurrentProcess());
+    DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x, '%.16s')\n", 
+            PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
 
     /* This should never happen */
     ASSERT(!SystemArgument2);