KD System Rewrite:
[reactos.git] / reactos / ntoskrnl / ke / timer.c
index 9ef0be5..49504f9 100644 (file)
@@ -107,12 +107,11 @@ KeInitializeTimerEx (PKTIMER Timer,
     
     /* Initialize the Dispatch Header */
     KeInitializeDispatcherHeader(&Timer->Header,
-                                 InternalNotificationTimer + Type,
+                                 TimerNotificationObject + Type,
                                  sizeof(KTIMER) / sizeof(ULONG),
                                  FALSE);
    
-    /* Initalize the List Head and other data */
-    InitializeListHead(&Timer->Header.WaitListHead);
+    /* Initalize the Other data */
     Timer->DueTime.QuadPart = 0;
     Timer->Period = 0;
 }
@@ -196,13 +195,11 @@ KeSetTimerEx (PKTIMER Timer,
     Timer->Dpc = Dpc;
     Timer->Period = Period;
     Timer->Header.SignalState = FALSE;
-    Timer->Header.Absolute = FALSE;
     
     /* Insert it */
     if (!KiInsertTimer(Timer, DueTime)) {
-    
-        /* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
-        DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
+
+       KiHandleExpiredTimer(Timer);
     };
 
     /* Release Dispatcher Lock */
@@ -220,26 +217,26 @@ KiExpireTimers(PKDPC Dpc,
                PVOID SystemArgument1,
                PVOID SystemArgument2)
 {
-    ULONG Eip = (ULONG)SystemArgument1;
-    PKTIMER Timer = NULL;
+    PKTIMER Timer;
     ULONGLONG InterruptTime;
     LIST_ENTRY ExpiredTimerList;
     PLIST_ENTRY CurrentEntry = NULL;
     KIRQL OldIrql;
 
     DPRINT("KiExpireTimers(Dpc: %x)\n", Dpc);
+    
+    /* Initialize the Expired Timer List */
+    InitializeListHead(&ExpiredTimerList);
 
     /* Lock the Database and Raise IRQL */
     OldIrql = KeAcquireDispatcherDatabaseLock();
-
-    /* Initialize the Expired Timer List */    
-    InitializeListHead(&ExpiredTimerList);
     
     /* Query Interrupt Times */ 
     InterruptTime = KeQueryInterruptTime();
 
     /* 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 */
         Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
@@ -247,6 +244,8 @@ KiExpireTimers(PKDPC Dpc,
         
         /* Check if we have to Expire it */
         if (InterruptTime < Timer->DueTime.QuadPart) break;
+        
+        CurrentEntry = CurrentEntry->Flink;
        
         /* Remove it from the Timer List, add it to the Expired List */
         RemoveEntryList(&Timer->TimerListEntry);
@@ -254,10 +253,7 @@ KiExpireTimers(PKDPC Dpc,
     }
     
     /* Expire the Timers */
-    while (!IsListEmpty(&ExpiredTimerList)) {
-        
-        /* Get the Next Entry */
-        CurrentEntry = RemoveHeadList(&ExpiredTimerList);
+    while ((CurrentEntry = RemoveHeadList(&ExpiredTimerList)) != &ExpiredTimerList) {
         
         /* Get the Timer */
         Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
@@ -268,8 +264,6 @@ KiExpireTimers(PKDPC Dpc,
     }
 
     DPRINT("Timers expired\n");
-    /* Add a Profile Event */
-    KiAddProfileEvent(ProfileTime, Eip);
 
     /* Release Dispatcher Lock */
     KeReleaseDispatcherDatabaseLock(OldIrql);
@@ -287,14 +281,17 @@ KiHandleExpiredTimer(PKTIMER Timer)
     LARGE_INTEGER DueTime;
     DPRINT("HandleExpiredTime(Timer %x)\n", Timer);
     
-    /* First of all, remove the Timer */
-    Timer->Header.Inserted = FALSE;
-    RemoveEntryList(&Timer->TimerListEntry);
+    if(Timer->Header.Inserted) {
+
+       /* First of all, remove the Timer */
+       Timer->Header.Inserted = FALSE;
+       RemoveEntryList(&Timer->TimerListEntry);
+    }
     
     /* Set it as Signaled */
     DPRINT("Setting Timer as Signaled\n");
     Timer->Header.SignalState = TRUE;
-    KiDispatcherObjectWake(&Timer->Header, 0);   
+    KiWaitTest(&Timer->Header, IO_NO_INCREMENT);   
 
     /* If the Timer is periodic, reinsert the timer with the new due time */
     if (Timer->Period) {
@@ -302,9 +299,9 @@ KiHandleExpiredTimer(PKTIMER Timer)
         /* Reinsert the Timer */
         DueTime.QuadPart = Timer->Period * -SYSTEM_TIME_UNITS_PER_MSEC;
         if (!KiInsertTimer(Timer, DueTime)) {
-        
-            /* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
-            DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
+
+           /* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
+           DPRINT("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
         };
     }
     
@@ -336,8 +333,10 @@ KiInsertTimer(PKTIMER Timer,
     
     DPRINT("KiInsertTimer(Timer %x DueTime %I64d)\n", Timer, DueTime.QuadPart);
     
-    /* Set it as Inserted */
+    /* Set default data */
     Timer->Header.Inserted = TRUE;
+    Timer->Header.Absolute = FALSE;
+    if (!Timer->Period) Timer->Header.SignalState = FALSE;
     
     /* Convert to relative time if needed */
     if (DueTime.u.HighPart >= 0) {