- Implement KiRecalculateDueTime to handle cases where a timeout wait has been interu...
authorAlex Ionescu <aionescu@gmail.com>
Sat, 22 Jul 2006 17:19:09 +0000 (17:19 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sat, 22 Jul 2006 17:19:09 +0000 (17:19 +0000)
svn path=/trunk/; revision=23229

reactos/ntoskrnl/KrnlFun.c
reactos/ntoskrnl/include/internal/ke_x.h
reactos/ntoskrnl/ke/queue.c
reactos/ntoskrnl/ke/wait.c

index 9894954..ddfb9ec 100644 (file)
@@ -45,8 +45,5 @@
 //  - Use pushlocks for handle implementation.\r
 //  - Figure out why cmd.exe won't close anymore.\r
 //\r
-// Ke:\r
-//  - Add code for interval recalulation when wait interrupted by an APC\r
-//\r
 ///////////////////////////////////////////////////////////////////////////////\r
 \r
index a56f872..4199406 100644 (file)
     }                                                                       \\r
 }\r
 \r
+//\r
+// Recalculates the due time\r
+//\r
+PLARGE_INTEGER\r
+FORCEINLINE\r
+KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime,\r
+                     IN PLARGE_INTEGER DueTime,\r
+                     IN OUT PLARGE_INTEGER NewDueTime)\r
+{\r
+    /* Don't do anything for absolute waits */\r
+    if (OriginalDueTime->QuadPart >= 0) return OriginalDueTime;\r
+\r
+    /* Otherwise, query the interrupt time and recalculate */\r
+    NewDueTime->QuadPart = KeQueryInterruptTime();\r
+    NewDueTime->QuadPart -= DueTime->QuadPart;\r
+    return NewDueTime;\r
+}\r
+\r
 //\r
 // Determines wether a thread should be added to the wait list\r
 //\r
index 7709d08..3149645 100644 (file)
@@ -249,6 +249,8 @@ KeRemoveQueue(IN PKQUEUE Queue,
     PKWAIT_BLOCK WaitBlock;
     PKTIMER Timer;
     BOOLEAN Swappable;
+    PLARGE_INTEGER OriginalDueTime = Timeout;
+    LARGE_INTEGER DueTime, NewDueTime;
     ASSERT_QUEUE(Queue);
     ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
 
@@ -396,7 +398,15 @@ KeRemoveQueue(IN PKQUEUE Queue,
                         &Timer->Header.WaitListHead;
 
                     /* Create Timer */
-                    KiInsertTimer(Timer, *Timeout);
+                    if (!KiInsertTimer(Timer, *Timeout))
+                    {
+                        /* FIXME */
+                        DPRINT1("If you see thie message contact Alex ASAP\n");
+                        KEBUGCHECK(0);
+                    }
+
+                    /* Set timer due time */
+                    DueTime.QuadPart = Timer->DueTime.QuadPart;
                 }
 
                 /* Close the loop */
@@ -431,8 +441,10 @@ KeRemoveQueue(IN PKQUEUE Queue,
                 /* Check if we had a timeout */
                 if (Timeout)
                 {
-                    DPRINT1("If you see this message, contact Alex ASAP\n");
-                    KEBUGCHECK(0);
+                    /* Recalculate due times */
+                    Timeout = KiRecalculateDueTime(OriginalDueTime,
+                                                   &DueTime,
+                                                   &NewDueTime);
                 }
             }
 
index 4ae86bf..92749c2 100644 (file)
@@ -275,6 +275,8 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
     PKTHREAD CurrentThread = KeGetCurrentThread();
     NTSTATUS WaitStatus = STATUS_SUCCESS;
     BOOLEAN Swappable;
+    PLARGE_INTEGER OriginalDueTime = Interval;
+    LARGE_INTEGER DueTime, NewDueTime;
 
     /* Check if the lock is already held */
     if (CurrentThread->WaitNext)
@@ -335,6 +337,9 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
                 break;
             }
 
+            /* Save due time */
+            DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
+
             /* Handle Kernel Queues */
             if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue);
 
@@ -360,9 +365,10 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
                 return WaitStatus;
             }
 
-            /* Check if we had a timeout */
-            DPRINT1("If you see this message, contact Alex ASAP\n");
-            KEBUGCHECK(0);
+            /* Recalculate due times */
+            Interval = KiRecalculateDueTime(OriginalDueTime,
+                                            &DueTime,
+                                            &NewDueTime);
         }
 
         /* Acquire again the lock */
@@ -392,6 +398,8 @@ KeWaitForSingleObject(IN PVOID Object,
     PKTHREAD CurrentThread = KeGetCurrentThread();
     NTSTATUS WaitStatus = STATUS_SUCCESS;
     BOOLEAN Swappable;
+    LARGE_INTEGER DueTime, NewDueTime;
+    PLARGE_INTEGER OriginalDueTime = Timeout;
 
     /* Check if the lock is already held */
     if (CurrentThread->WaitNext)
@@ -506,6 +514,9 @@ KeWaitForSingleObject(IN PVOID Object,
                     WaitStatus = STATUS_TIMEOUT;
                     goto DontWait;
                 }
+
+                /* Set the current due time */
+                DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
             }
             else
             {
@@ -538,8 +549,10 @@ KeWaitForSingleObject(IN PVOID Object,
             /* Check if we had a timeout */
             if (Timeout)
             {
-                DPRINT1("If you see this message, contact Alex ASAP\n");
-                KEBUGCHECK(0);
+                /* Recalculate due times */
+                Timeout = KiRecalculateDueTime(OriginalDueTime,
+                                               &DueTime,
+                                               &NewDueTime);
             }
         }
 
@@ -583,6 +596,8 @@ KeWaitForMultipleObjects(IN ULONG Count,
     ULONG WaitIndex;
     NTSTATUS WaitStatus = STATUS_SUCCESS;
     BOOLEAN Swappable;
+    PLARGE_INTEGER OriginalDueTime = Timeout;
+    LARGE_INTEGER DueTime, NewDueTime;
 
     /* Set the Current Thread */
     CurrentThread = KeGetCurrentThread();
@@ -781,6 +796,9 @@ KeWaitForMultipleObjects(IN ULONG Count,
                     WaitStatus = STATUS_TIMEOUT;
                     goto DontWait;
                 }
+
+                /* Set the current due time */
+                DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
             }
 
             /* Insert into Object's Wait List*/
@@ -819,8 +837,10 @@ KeWaitForMultipleObjects(IN ULONG Count,
             /* Check if we had a timeout */
             if (Timeout)
             {
-                DPRINT1("If you see this message, contact Alex ASAP\n");
-                KEBUGCHECK(0);
+                /* Recalculate due times */
+                Timeout = KiRecalculateDueTime(OriginalDueTime,
+                                               &DueTime,
+                                               &NewDueTime);
             }
 
             /* Acquire again the lock */