update for HEAD-2003091401
[reactos.git] / ntoskrnl / ke / wait.c
index fb6b191..6fc50e8 100644 (file)
@@ -68,9 +68,8 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait)
 
 VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait)
 {
-  DPRINT("KeReleaseDispatcherDatabaseLockAtDpcLevel(Wait %x)\n", Wait);
-  assert(Wait == WaitSet);
-  if (!Wait)
+  DPRINT("KeReleaseDispatcherDatabaseLockAtDpcLevel(Wait %x) WaitSet=%x\n", Wait, WaitSet);
+  if (Wait == WaitSet)
     {
       Owner = NULL;
       KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
@@ -79,9 +78,8 @@ VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait)
 
 VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
 {
-   DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x)\n",Wait);
-   assert(Wait==WaitSet);
-   if (!Wait)
+   DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x) WaitSet=%x\n",Wait,WaitSet);
+   if (Wait == WaitSet)
      {
        Owner = NULL;
        KeReleaseSpinLock(&DispatcherDatabaseLock, oldlvl);
@@ -137,7 +135,7 @@ KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
             if (Thread == NULL)
             {
                DPRINT("Thread == NULL!\n");
-               KeBugCheck(0);
+               KEBUGCHECK(0);
             }
             Abandoned = Mutex->Abandoned;
             if (Thread != NULL)
@@ -150,7 +148,7 @@ KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
 
       default:
          DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", __FILE__, __LINE__, hdr);
-         KeBugCheck(0);
+         KEBUGCHECK(0);
    }
 
    return Abandoned;
@@ -188,9 +186,9 @@ KiIsObjectSignalled(DISPATCHER_HEADER * hdr,
    }
 }
 
-VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus)
+VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
 {
-   PKWAIT_BLOCK WaitBlock;
+   PKWAIT_BLOCK WaitBlock, PrevWaitBlock;
    BOOLEAN WasWaiting = FALSE;
 
    KeAcquireDispatcherDatabaseLock(FALSE);
@@ -202,12 +200,18 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus)
      }
    while (WaitBlock != NULL)
      {
-       RemoveEntryList(&WaitBlock->WaitListEntry);
+       if (WaitBlock->WaitListEntry.Flink != NULL && WaitBlock->WaitListEntry.Blink != NULL)
+         { 
+           RemoveEntryList (&WaitBlock->WaitListEntry);
+            WaitBlock->WaitListEntry.Flink = WaitBlock->WaitListEntry.Blink = NULL;
+         }
+       PrevWaitBlock = WaitBlock;
        WaitBlock = WaitBlock->NextWaitBlock;
+       PrevWaitBlock->NextWaitBlock = NULL;
      }
    Thread->Tcb.WaitBlockList = NULL;
 
-   if (WasWaiting)
+   if (WasWaiting && Unblock)
      {
        PsUnblockThread(Thread, &WaitStatus);
      }
@@ -243,6 +247,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
       WaiterHead = CONTAINING_RECORD(EnumEntry, KWAIT_BLOCK, WaitListEntry);
       DPRINT("current_entry %x current %x\n", EnumEntry, WaiterHead);
       EnumEntry = EnumEntry->Flink;
+      assert(WaiterHead->Thread != NULL);
       assert(WaiterHead->Thread->WaitBlockList != NULL);
 
       Abandoned = FALSE;
@@ -252,7 +257,11 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
          DPRINT("WaitAny: Remove all wait blocks.\n");
          for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
          {
-            RemoveEntryList(&Waiter->WaitListEntry);
+            if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL)
+             {
+               RemoveEntryList(&Waiter->WaitListEntry);
+               Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL;
+             }
          }
 
          WaiterHead->Thread->WaitBlockList = NULL;
@@ -287,8 +296,12 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
          {
             for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
             {
-               RemoveEntryList(&Waiter->WaitListEntry);
-
+               if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL)
+              {
+                 RemoveEntryList(&Waiter->WaitListEntry);
+                 Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL;
+              }
+         
                if (Waiter->WaitType == WaitAll)
                {
                   Abandoned = KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread)
@@ -373,11 +386,14 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
        return(KeDispatcherObjectWakeOne(hdr));
      }
    DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type);
-   KeBugCheck(0);
+   KEBUGCHECK(0);
    return(FALSE);
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 KeWaitForSingleObject(PVOID Object,
                       KWAIT_REASON WaitReason,
@@ -423,6 +439,9 @@ KiGetWaitableObjectFromObject(PVOID Object)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 KeWaitForMultipleObjects(ULONG Count,
                          PVOID Object[],
@@ -482,7 +501,7 @@ KeWaitForMultipleObjects(ULONG Count,
    {
       KeAcquireDispatcherDatabaseLock(FALSE);
 
-         /*
+      /*
        * If we are going to wait alertably and a user apc is pending
        * then return
        */
@@ -634,8 +653,8 @@ KeWaitForMultipleObjects(ULONG Count,
       //io completion
       if (CurrentThread->Queue)
       {
-         CurrentThread->Queue->RunningThreads--;   
-         if (WaitReason != WrQueue && CurrentThread->Queue->RunningThreads < CurrentThread->Queue->MaximumThreads &&
+         CurrentThread->Queue->CurrentCount--;   
+         if (WaitReason != WrQueue && CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
              !IsListEmpty(&CurrentThread->Queue->EntryListHead))
          {
             KeDispatcherObjectWake(&CurrentThread->Queue->Header);
@@ -647,7 +666,7 @@ KeWaitForMultipleObjects(ULONG Count,
       //io completion
       if (CurrentThread->Queue)
       {
-         CurrentThread->Queue->RunningThreads++;
+         CurrentThread->Queue->CurrentCount++;
       }
 
 
@@ -729,6 +748,9 @@ NtWaitForMultipleObjects(IN ULONG Count,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 NtWaitForSingleObject(IN HANDLE Object,
                      IN BOOLEAN Alertable,