mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
- 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). svn path=/trunk/; revision=37212
This commit is contained in:
parent
04b0bb8994
commit
b21beacd60
1 changed files with 25 additions and 19 deletions
|
@ -436,8 +436,7 @@ PLIST_ENTRY
|
|||
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 @@ KeRundownQueue(IN PKQUEUE Queue)
|
|||
|
||||
/* Get the Dispatcher Lock */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Make sure the list is not empty */
|
||||
if (!IsListEmpty(&Queue->EntryListHead))
|
||||
|
||||
/* Check if the list is empty */
|
||||
FirstEntry = Queue->EntryListHead.Flink;
|
||||
if (FirstEntry == &Queue->EntryListHead)
|
||||
{
|
||||
/* Remove it */
|
||||
FirstEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
/* We won't return anything */
|
||||
FirstEntry = NULL;
|
||||
}
|
||||
|
||||
/* Unlink threads and clear their Thread->Queue */
|
||||
ListHead = &Queue->ThreadListHead;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (ListHead != NextEntry)
|
||||
else
|
||||
{
|
||||
/* Get the Entry's Thread */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue