- 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).

svn path=/trunk/; revision=23229
This commit is contained in:
Alex Ionescu 2006-07-22 17:19:09 +00:00
parent d310e2ae8c
commit 7af4849812
4 changed files with 60 additions and 13 deletions

View file

@ -45,8 +45,5 @@
// - Use pushlocks for handle implementation. // - Use pushlocks for handle implementation.
// - Figure out why cmd.exe won't close anymore. // - Figure out why cmd.exe won't close anymore.
// //
// Ke:
// - Add code for interval recalulation when wait interrupted by an APC
//
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View file

@ -155,6 +155,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 // Determines wether a thread should be added to the wait list
// //

View file

@ -249,6 +249,8 @@ KeRemoveQueue(IN PKQUEUE Queue,
PKWAIT_BLOCK WaitBlock; PKWAIT_BLOCK WaitBlock;
PKTIMER Timer; PKTIMER Timer;
BOOLEAN Swappable; BOOLEAN Swappable;
PLARGE_INTEGER OriginalDueTime = Timeout;
LARGE_INTEGER DueTime, NewDueTime;
ASSERT_QUEUE(Queue); ASSERT_QUEUE(Queue);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@ -396,7 +398,15 @@ KeRemoveQueue(IN PKQUEUE Queue,
&Timer->Header.WaitListHead; &Timer->Header.WaitListHead;
/* Create Timer */ /* 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 */ /* Close the loop */
@ -431,8 +441,10 @@ KeRemoveQueue(IN PKQUEUE Queue,
/* Check if we had a timeout */ /* Check if we had a timeout */
if (Timeout) if (Timeout)
{ {
DPRINT1("If you see this message, contact Alex ASAP\n"); /* Recalculate due times */
KEBUGCHECK(0); Timeout = KiRecalculateDueTime(OriginalDueTime,
&DueTime,
&NewDueTime);
} }
} }

View file

@ -275,6 +275,8 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
PKTHREAD CurrentThread = KeGetCurrentThread(); PKTHREAD CurrentThread = KeGetCurrentThread();
NTSTATUS WaitStatus = STATUS_SUCCESS; NTSTATUS WaitStatus = STATUS_SUCCESS;
BOOLEAN Swappable; BOOLEAN Swappable;
PLARGE_INTEGER OriginalDueTime = Interval;
LARGE_INTEGER DueTime, NewDueTime;
/* Check if the lock is already held */ /* Check if the lock is already held */
if (CurrentThread->WaitNext) if (CurrentThread->WaitNext)
@ -335,6 +337,9 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
break; break;
} }
/* Save due time */
DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
/* Handle Kernel Queues */ /* Handle Kernel Queues */
if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue);
@ -360,9 +365,10 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
return WaitStatus; return WaitStatus;
} }
/* Check if we had a timeout */ /* Recalculate due times */
DPRINT1("If you see this message, contact Alex ASAP\n"); Interval = KiRecalculateDueTime(OriginalDueTime,
KEBUGCHECK(0); &DueTime,
&NewDueTime);
} }
/* Acquire again the lock */ /* Acquire again the lock */
@ -392,6 +398,8 @@ KeWaitForSingleObject(IN PVOID Object,
PKTHREAD CurrentThread = KeGetCurrentThread(); PKTHREAD CurrentThread = KeGetCurrentThread();
NTSTATUS WaitStatus = STATUS_SUCCESS; NTSTATUS WaitStatus = STATUS_SUCCESS;
BOOLEAN Swappable; BOOLEAN Swappable;
LARGE_INTEGER DueTime, NewDueTime;
PLARGE_INTEGER OriginalDueTime = Timeout;
/* Check if the lock is already held */ /* Check if the lock is already held */
if (CurrentThread->WaitNext) if (CurrentThread->WaitNext)
@ -506,6 +514,9 @@ KeWaitForSingleObject(IN PVOID Object,
WaitStatus = STATUS_TIMEOUT; WaitStatus = STATUS_TIMEOUT;
goto DontWait; goto DontWait;
} }
/* Set the current due time */
DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
} }
else else
{ {
@ -538,8 +549,10 @@ KeWaitForSingleObject(IN PVOID Object,
/* Check if we had a timeout */ /* Check if we had a timeout */
if (Timeout) if (Timeout)
{ {
DPRINT1("If you see this message, contact Alex ASAP\n"); /* Recalculate due times */
KEBUGCHECK(0); Timeout = KiRecalculateDueTime(OriginalDueTime,
&DueTime,
&NewDueTime);
} }
} }
@ -583,6 +596,8 @@ KeWaitForMultipleObjects(IN ULONG Count,
ULONG WaitIndex; ULONG WaitIndex;
NTSTATUS WaitStatus = STATUS_SUCCESS; NTSTATUS WaitStatus = STATUS_SUCCESS;
BOOLEAN Swappable; BOOLEAN Swappable;
PLARGE_INTEGER OriginalDueTime = Timeout;
LARGE_INTEGER DueTime, NewDueTime;
/* Set the Current Thread */ /* Set the Current Thread */
CurrentThread = KeGetCurrentThread(); CurrentThread = KeGetCurrentThread();
@ -781,6 +796,9 @@ KeWaitForMultipleObjects(IN ULONG Count,
WaitStatus = STATUS_TIMEOUT; WaitStatus = STATUS_TIMEOUT;
goto DontWait; goto DontWait;
} }
/* Set the current due time */
DueTime.QuadPart = ThreadTimer->DueTime.QuadPart;
} }
/* Insert into Object's Wait List*/ /* Insert into Object's Wait List*/
@ -819,8 +837,10 @@ KeWaitForMultipleObjects(IN ULONG Count,
/* Check if we had a timeout */ /* Check if we had a timeout */
if (Timeout) if (Timeout)
{ {
DPRINT1("If you see this message, contact Alex ASAP\n"); /* Recalculate due times */
KEBUGCHECK(0); Timeout = KiRecalculateDueTime(OriginalDueTime,
&DueTime,
&NewDueTime);
} }
/* Acquire again the lock */ /* Acquire again the lock */