Author: ion Date: Sat Jul 22 21:19:09 2006 New Revision: 23229
URL: http://svn.reactos.org/svn/reactos?rev=23229&view=rev Log: - Implement KiRecalculateDueTime to handle cases where a timeout wait has been interupted by an APC or alerted, and it needs to be recalculated in the relative case. (This fixes the "contact alex" bugcheck).
Modified: trunk/reactos/ntoskrnl/KrnlFun.c trunk/reactos/ntoskrnl/include/internal/ke_x.h trunk/reactos/ntoskrnl/ke/queue.c trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/KrnlFun.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=2322... ============================================================================== --- trunk/reactos/ntoskrnl/KrnlFun.c (original) +++ trunk/reactos/ntoskrnl/KrnlFun.c Sat Jul 22 21:19:09 2006 @@ -45,8 +45,5 @@ // - Use pushlocks for handle implementation. // - Figure out why cmd.exe won't close anymore. // -// Ke: -// - Add code for interval recalulation when wait interrupted by an APC -// ///////////////////////////////////////////////////////////////////////////////
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke_x.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ke_x.h Sat Jul 22 21:19:09 2006 @@ -156,6 +156,24 @@ }
// +// Recalculates the due time +// +PLARGE_INTEGER +FORCEINLINE +KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, + IN PLARGE_INTEGER DueTime, + IN OUT PLARGE_INTEGER NewDueTime) +{ + /* Don't do anything for absolute waits */ + if (OriginalDueTime->QuadPart >= 0) return OriginalDueTime; + + /* Otherwise, query the interrupt time and recalculate */ + NewDueTime->QuadPart = KeQueryInterruptTime(); + NewDueTime->QuadPart -= DueTime->QuadPart; + return NewDueTime; +} + +// // Determines wether a thread should be added to the wait list // #define KiCheckThreadStackSwap(WaitMode, Thread, Swappable) \
Modified: trunk/reactos/ntoskrnl/ke/queue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/queue.c?rev=232... ============================================================================== --- trunk/reactos/ntoskrnl/ke/queue.c (original) +++ trunk/reactos/ntoskrnl/ke/queue.c Sat Jul 22 21:19:09 2006 @@ -249,6 +249,8 @@ 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 @@ &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 @@ /* 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); } }
Modified: trunk/reactos/ntoskrnl/ke/wait.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/wait.c?rev=2322... ============================================================================== --- trunk/reactos/ntoskrnl/ke/wait.c (original) +++ trunk/reactos/ntoskrnl/ke/wait.c Sat Jul 22 21:19:09 2006 @@ -275,6 +275,8 @@ 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) @@ -334,6 +336,9 @@ WaitStatus = STATUS_SUCCESS; break; } + + /* Save due time */ + DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
/* Handle Kernel Queues */ if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); @@ -360,9 +365,10 @@ 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 @@ 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 @@ WaitStatus = STATUS_TIMEOUT; goto DontWait; } + + /* Set the current due time */ + DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; } else { @@ -538,8 +549,10 @@ /* 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 @@ 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 @@ 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 @@ /* 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 */