mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 20:33:04 +00:00
don't remove the timer from the list before walking to the next timer. also handle over-due timers in KeSetTimerEx(). This should make the system bootable again.
svn path=/trunk/; revision=13566
This commit is contained in:
parent
40623e356a
commit
04380923bf
1 changed files with 25 additions and 22 deletions
|
@ -201,8 +201,7 @@ KeSetTimerEx (PKTIMER Timer,
|
||||||
/* Insert it */
|
/* Insert it */
|
||||||
if (!KiInsertTimer(Timer, DueTime)) {
|
if (!KiInsertTimer(Timer, DueTime)) {
|
||||||
|
|
||||||
/* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
|
KiHandleExpiredTimer(Timer);
|
||||||
DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Release Dispatcher Lock */
|
/* Release Dispatcher Lock */
|
||||||
|
@ -221,7 +220,7 @@ KiExpireTimers(PKDPC Dpc,
|
||||||
PVOID SystemArgument2)
|
PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
ULONG Eip = (ULONG)SystemArgument1;
|
ULONG Eip = (ULONG)SystemArgument1;
|
||||||
PKTIMER Timer = NULL;
|
PKTIMER Timer;
|
||||||
ULONGLONG InterruptTime;
|
ULONGLONG InterruptTime;
|
||||||
LIST_ENTRY ExpiredTimerList;
|
LIST_ENTRY ExpiredTimerList;
|
||||||
PLIST_ENTRY CurrentEntry = NULL;
|
PLIST_ENTRY CurrentEntry = NULL;
|
||||||
|
@ -229,35 +228,36 @@ KiExpireTimers(PKDPC Dpc,
|
||||||
|
|
||||||
DPRINT("KiExpireTimers(Dpc: %x)\n", Dpc);
|
DPRINT("KiExpireTimers(Dpc: %x)\n", Dpc);
|
||||||
|
|
||||||
/* Lock the Database and Raise IRQL */
|
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
|
||||||
|
|
||||||
/* Initialize the Expired Timer List */
|
/* Initialize the Expired Timer List */
|
||||||
InitializeListHead(&ExpiredTimerList);
|
InitializeListHead(&ExpiredTimerList);
|
||||||
|
|
||||||
|
/* Lock the Database and Raise IRQL */
|
||||||
|
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||||
|
|
||||||
/* Query Interrupt Times */
|
/* Query Interrupt Times */
|
||||||
InterruptTime = KeQueryInterruptTime();
|
InterruptTime = KeQueryInterruptTime();
|
||||||
|
|
||||||
/* Loop through the Timer List and remove Expired Timers. Insert them into the Expired Listhead */
|
/* Loop through the Timer List and remove Expired Timers. Insert them into the Expired Listhead */
|
||||||
for (CurrentEntry = KiTimerListHead.Flink; CurrentEntry != &KiTimerListHead; CurrentEntry = CurrentEntry->Flink) {
|
CurrentEntry = KiTimerListHead.Flink;
|
||||||
|
while (CurrentEntry != &KiTimerListHead) {
|
||||||
|
|
||||||
/* Get the Current Timer */
|
/* Get the Current Timer */
|
||||||
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
|
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
|
||||||
DPRINT("Looping for Timer: %x. Duetime: %I64d. InterruptTime %I64d \n", Timer, Timer->DueTime.QuadPart, InterruptTime);
|
DPRINT("Looping for Timer: %x. Duetime: %I64d. InterruptTime %I64d \n", Timer, Timer->DueTime.QuadPart, InterruptTime);
|
||||||
|
|
||||||
/* Check if we have to Expire it */
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
if (InterruptTime < Timer->DueTime.QuadPart) break;
|
|
||||||
|
|
||||||
/* Remove it from the Timer List, add it to the Expired List */
|
/* Check if we have to Expire it */
|
||||||
RemoveEntryList(&Timer->TimerListEntry);
|
if (InterruptTime >= Timer->DueTime.QuadPart) {
|
||||||
InsertTailList(&ExpiredTimerList, &Timer->TimerListEntry);
|
|
||||||
|
/* Remove it from the Timer List, add it to the Expired List */
|
||||||
|
RemoveEntryList(&Timer->TimerListEntry);
|
||||||
|
InsertTailList(&ExpiredTimerList, &Timer->TimerListEntry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expire the Timers */
|
/* Expire the Timers */
|
||||||
while (!IsListEmpty(&ExpiredTimerList)) {
|
while ((CurrentEntry = RemoveHeadList(&ExpiredTimerList)) != &ExpiredTimerList) {
|
||||||
|
|
||||||
/* Get the Next Entry */
|
|
||||||
CurrentEntry = RemoveHeadList(&ExpiredTimerList);
|
|
||||||
|
|
||||||
/* Get the Timer */
|
/* Get the Timer */
|
||||||
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
|
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
|
||||||
|
@ -287,9 +287,12 @@ KiHandleExpiredTimer(PKTIMER Timer)
|
||||||
LARGE_INTEGER DueTime;
|
LARGE_INTEGER DueTime;
|
||||||
DPRINT("HandleExpiredTime(Timer %x)\n", Timer);
|
DPRINT("HandleExpiredTime(Timer %x)\n", Timer);
|
||||||
|
|
||||||
/* First of all, remove the Timer */
|
if(Timer->Header.Inserted) {
|
||||||
Timer->Header.Inserted = FALSE;
|
|
||||||
RemoveEntryList(&Timer->TimerListEntry);
|
/* First of all, remove the Timer */
|
||||||
|
Timer->Header.Inserted = FALSE;
|
||||||
|
RemoveEntryList(&Timer->TimerListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set it as Signaled */
|
/* Set it as Signaled */
|
||||||
DPRINT("Setting Timer as Signaled\n");
|
DPRINT("Setting Timer as Signaled\n");
|
||||||
|
@ -303,8 +306,8 @@ KiHandleExpiredTimer(PKTIMER Timer)
|
||||||
DueTime.QuadPart = Timer->Period * -SYSTEM_TIME_UNITS_PER_MSEC;
|
DueTime.QuadPart = Timer->Period * -SYSTEM_TIME_UNITS_PER_MSEC;
|
||||||
if (!KiInsertTimer(Timer, DueTime)) {
|
if (!KiInsertTimer(Timer, DueTime)) {
|
||||||
|
|
||||||
/* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
|
/* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
|
||||||
DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
|
DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue