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:
Thomas Bluemel 2005-02-14 16:41:53 +00:00
parent 40623e356a
commit 04380923bf

View file

@ -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");
}; };
} }