[ros-diffs] [fireball] 37212: - Fix behavior of KeRundownQueue (save the next link before freeing it and use proper locking and enumeration code). - This fixes behavior of I/O completion ports (thanks to Stefan and Alex for testing, reporting and fixing).

fireball at svn.reactos.org fireball at svn.reactos.org
Fri Nov 7 11:56:49 CET 2008


Author: fireball
Date: Wed Nov  5 18:03:04 2008
New Revision: 37212

URL: http://svn.reactos.org/svn/reactos?rev=37212&view=rev
Log:
- Fix behavior of KeRundownQueue (save the next link before freeing it and use proper locking and enumeration code).
- This fixes behavior of I/O completion ports (thanks to Stefan and Alex for testing, reporting and fixing).

Modified:
    trunk/reactos/ntoskrnl/ke/queue.c

Modified: trunk/reactos/ntoskrnl/ke/queue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/queue.c?rev=37212&r1=37211&r2=37212&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/queue.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/queue.c [iso-8859-1] Wed Nov  5 18:03:04 2008
@@ -436,8 +436,7 @@
 NTAPI
 KeRundownQueue(IN PKQUEUE Queue)
 {
-    PLIST_ENTRY ListHead, NextEntry;
-    PLIST_ENTRY FirstEntry = NULL;
+    PLIST_ENTRY FirstEntry, NextEntry;
     PKTHREAD Thread;
     KIRQL OldIrql;
     ASSERT_QUEUE(Queue);
@@ -446,34 +445,41 @@
 
     /* Get the Dispatcher Lock */
     OldIrql = KiAcquireDispatcherLock();
-
-    /* Make sure the list is not empty */
-    if (!IsListEmpty(&Queue->EntryListHead))
-    {
-        /* Remove it */
-        FirstEntry = RemoveHeadList(&Queue->EntryListHead);
-    }
-
-    /* Unlink threads and clear their Thread->Queue */
-    ListHead = &Queue->ThreadListHead;
-    NextEntry = ListHead->Flink;
-    while (ListHead != NextEntry)
-    {
-        /* Get the Entry's Thread */
+ 
+    /* Check if the list is empty */
+    FirstEntry = Queue->EntryListHead.Flink;
+    if (FirstEntry == &Queue->EntryListHead)
+    {
+        /* We won't return anything */
+        FirstEntry = NULL;
+    }
+    else
+    {
+        /* Remove this entry */
+        RemoveEntryList(&Queue->EntryListHead);
+    }
+ 
+    /* Loop the list */
+    while (!IsListEmpty(&Queue->ThreadListHead))
+    {
+        /* Get the next entry */
+        NextEntry = Queue->ThreadListHead.Flink;
+ 
+        /* Get the associated thread */
         Thread = CONTAINING_RECORD(NextEntry, KTHREAD, QueueListEntry);
 
-        /* Kill its Queue */
+        /* Clear its queue */
         Thread->Queue = NULL;
 
         /* Remove this entry */
         RemoveEntryList(NextEntry);
-
-        /* Get the next entry */
-        NextEntry = NextEntry->Flink;
-    }
-
-    /* Release the lock and return */
-    KiReleaseDispatcherLock(OldIrql);
+    }
+
+    /* Release the dispatcher lock */
+    KiReleaseDispatcherLockFromDpcLevel();
+ 
+    /* Exit the dispatcher and return the first entry (if any) */
+    KiExitDispatcher(OldIrql);
     return FirstEntry;
 }
 



More information about the Ros-diffs mailing list