- Fixed the broken implementation of KeFlushQueueApc.  
- Fixed some locking operations with two spin locks.
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c

Modified: trunk/reactos/ntoskrnl/ke/apc.c
--- trunk/reactos/ntoskrnl/ke/apc.c	2005-07-26 19:02:31 UTC (rev 16751)
+++ trunk/reactos/ntoskrnl/ke/apc.c	2005-07-26 19:11:25 UTC (rev 16752)
@@ -270,14 +270,14 @@
     */
     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 @@
 
     } 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 @@
     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;
+       if (ApcEntry == NULL)
+       {
+          ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
+       }
+       else
+       {
+          CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
+          CurrentEntry = CurrentEntry->Flink;
+       }
+       CurrentEntry->Flink = NULL;
 
-        /* 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);
+       /* 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 @@
     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 @@
     } 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);
 }

Modified: trunk/reactos/ntoskrnl/ps/kill.c
--- trunk/reactos/ntoskrnl/ps/kill.c	2005-07-26 19:02:31 UTC (rev 16751)
+++ trunk/reactos/ntoskrnl/ps/kill.c	2005-07-26 19:11:25 UTC (rev 16752)
@@ -213,7 +213,7 @@
     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 @@
     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);
+       /* Get the APC */
+       Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
 
-            /* Move to the next one */
-            CurrentApc = CurrentApc->Flink;
+       /* 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);
-            }
-        }
-        while (CurrentApc != ApcEntry);
+       /* 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 @@
                  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 @@
     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);