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=232…
==============================================================================
--- 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/…
==============================================================================
--- 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=23…
==============================================================================
--- 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=232…
==============================================================================
--- 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 */