Keith Packard wrote:
> Yes, it looks like you're correct -- every example I could find would 
> ensure that pending device input was marked in checkForInput.  There are 
> some odd examples of this however, which are somewhat instructive to 
> examine:
> 
>  a)   The original A/UX server had checkForInput marked from the SIGIO 
>       handler and read device events in ProcessInputEvents.

If WaitForSomething returns after the checkForInput check allowing
ProcessInputEvents be executed before the timers check, this case changes
nothing.  It doesn't matter when the events reading was done, before the
ProcessInputEvents or during its execution.

BTW I forgot to mention one other advantage of checkForInput.  It reflects
the events queued from SIGIO handlers but the devicesReadable check misses
such events.

>  b)   Many old servers never set checkForInput.  The default values
>       point at two different values, so ProcessInput events would be 
>       called each time around the Dispatch loop.

Unfortunately, if we assume that some events can be queued from SIGIO handlers
this case is hopeless completely.
With conditions:
- timers should not be processed if there are input events queued but not
  processed by ProcessInputEvents,
- checkForInput can't be used because it always true and with such check
  the timers will never be processed,
- devicesReadable check doesn't reflect input events queued in SIGIO handlers
  and can't be used because it doesn't fulfil the first condition
the problem becomes unsolvable.

> > Is it possible to check changes in the file descriptors set instead of just
> > the fact that some timer was processed?
> 
> That would only be necessary if performance across timer execution were a 
> critical factor -- essentially what we're forcing by returning 0 is 
> another call to select, which will do all of the file descriptor checking 
> necessary.  It seems simpler to let the existing code handle this case.

OK.  I made the next (and hope it's final) version.
In both branches (after the select) the subroutine returns if at least one
time is expired.

-- 
 Ivan U. Pascal         |   e-mail: [EMAIL PROTECTED]
   Administrator of     |   Tomsk State University
     University Network |       Tomsk, Russia
--- xc/programs/Xserver/os/WaitFor.c.orig       Wed Sep 17 17:24:12 2003
+++ xc/programs/Xserver/os/WaitFor.c            Wed Sep 24 19:15:53 2003
@@ -131,17 +131,12 @@
  *     pClientsReady is an array to store ready client->index values into.
  *****************/
 
-static INT32 timeTilFrob = 0;          /* while screen saving */
-
 int
 WaitForSomething(int *pClientsReady)
 {
     int i;
     struct timeval waittime, *wt;
     INT32 timeout = 0;
-#ifdef DPMSExtension
-    INT32 standbyTimeout = 0, suspendTimeout = 0, offTimeout = 0;
-#endif
     fd_set clientsReadable;
     fd_set clientsWritable;
     int curclient;
@@ -188,138 +183,17 @@
        else
        {
 #endif
-#ifdef DPMSExtension
-       if (ScreenSaverTime > 0 || DPMSEnabled || timers)
-#else
-       if (ScreenSaverTime > 0 || timers)
-#endif
-           now = GetTimeInMillis();
-       wt = NULL;
+        wt = NULL;
        if (timers)
-       {
-           while (timers && (int) (timers->expires - now) <= 0)
-               DoTimer(timers, now, &timers);
-           if (timers)
-           {
-               timeout = timers->expires - now;
-               waittime.tv_sec = timeout / MILLI_PER_SECOND;
-               waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
-                   (1000000 / MILLI_PER_SECOND);
-               wt = &waittime;
-           }
-       }
-       if (ScreenSaverTime > 0
-#ifdef DPMSExtension
-           || (DPMSEnabled &&
-            (DPMSStandbyTime > 0 || DPMSSuspendTime > 0 || DPMSOffTime > 0))
-#endif
-       ) {
-#ifdef DPMSExtension
-           if (ScreenSaverTime > 0)
-#endif
-               timeout = (ScreenSaverTime -
-                          (now - lastDeviceEventTime.milliseconds));
-#ifdef DPMSExtension
-           if (DPMSStandbyTime > 0)
-               standbyTimeout = (DPMSStandbyTime -
-                                 (now - lastDeviceEventTime.milliseconds));
-           if (DPMSSuspendTime > 0)
-               suspendTimeout = (DPMSSuspendTime -
-                                 (now - lastDeviceEventTime.milliseconds));
-           if (DPMSOffTime > 0)
-               offTimeout = (DPMSOffTime -
-                             (now - lastDeviceEventTime.milliseconds));
-#endif /* DPMSExtension */
-
-           if (
-               timeout <= 0
-#ifdef DPMSExtension
-                && ScreenSaverTime > 0
-#endif /* DPMSExtension */
-           ) {
-               INT32 timeSinceSave;
-
-               timeSinceSave = -timeout;
-               if (timeSinceSave >= timeTilFrob && timeTilFrob >= 0)
-               {
-                   ResetOsBuffers(); /* not ideal, but better than nothing */
-                   SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
-#ifdef DPMSExtension
-                   if (ScreenSaverInterval > 0 &&
-                       DPMSPowerLevel == DPMSModeOn)
-#else
-                   if (ScreenSaverInterval)
-#endif /* DPMSExtension */
-                       /* round up to the next ScreenSaverInterval */
-                       timeTilFrob = ScreenSaverInterval *
-                               ((timeSinceSave + ScreenSaverInterval) /
-                                       ScreenSaverInterval);
-                   else
-                       timeTilFrob = -1;
-               }
-               timeout = timeTilFrob - timeSinceSave;
-           }
-           else
-           {
-               if (ScreenSaverTime > 0 && timeout > ScreenSaverTime)
-                   timeout = ScreenSaverTime;
-               timeTilFrob = 0;
-           }
-#ifdef DPMSExtension
-           if (DPMSEnabled)
-           {
-               if (standbyTimeout > 0 
-                   && (timeout <= 0 || timeout > standbyTimeout))
-                   timeout = standbyTimeout;
-               if (suspendTimeout > 0 
-                   && (timeout <= 0 || timeout > suspendTimeout))
-                   timeout = suspendTimeout;
-               if (offTimeout > 0 
-                   && (timeout <= 0 || timeout > offTimeout))
-                   timeout = offTimeout;
-           }
-#endif
-           if (timeout > 0 && (!wt || timeout < (int) (timers->expires - now)))
-           {
-               waittime.tv_sec = timeout / MILLI_PER_SECOND;
-               waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
-                                       (1000000 / MILLI_PER_SECOND);
-               wt = &waittime;
-           }
-#ifdef DPMSExtension
-           /* don't bother unless it's switched on */
-           if (DPMSEnabled) {
-               /*
-                * If this mode's enabled, and if the time's come
-                * and if we're still at a lesser mode, do it now.
-                */
-               if (DPMSStandbyTime > 0) {
-                   if (standbyTimeout <= 0) {
-                       if (DPMSPowerLevel < DPMSModeStandby) {
-                           DPMSSet(DPMSModeStandby);
-                       }
-                   }
-               }
-               /*
-                * and ditto.  Note that since these modes can have the
-                * same timeouts, they can happen at the same time.
-                */
-               if (DPMSSuspendTime > 0) {
-                   if (suspendTimeout <= 0) {
-                       if (DPMSPowerLevel < DPMSModeSuspend) {
-                           DPMSSet(DPMSModeSuspend);
-                       }
-                   }
-               }
-               if (DPMSOffTime > 0) {
-                   if (offTimeout <= 0) {
-                       if (DPMSPowerLevel < DPMSModeOff) {
-                           DPMSSet(DPMSModeOff);
-                       }
-                   }
-               }
-           }
-#endif
+        {
+            now = GetTimeInMillis();
+           timeout = timers->expires - now;
+            if (timeout < 0)
+                timeout = 0;
+           waittime.tv_sec = timeout / MILLI_PER_SECOND;
+           waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
+                              (1000000 / MILLI_PER_SECOND);
+           wt = &waittime;
        }
        XFD_COPYSET(&AllSockets, &LastSelectMask);
 #ifdef SMART_SCHEDULE
@@ -398,18 +272,42 @@
                break;
            }
 #endif
+           if (*checkForInput[0] != *checkForInput[1])
+               return 0;
+
            if (timers)
            {
+                int expired = 0;
                now = GetTimeInMillis();
+               if ((int) (timers->expires - now) <= 0)
+                   expired = 1;
+
                while (timers && (int) (timers->expires - now) <= 0)
                    DoTimer(timers, now, &timers);
+
+                if (expired)
+                    return 0;
            }
-           if (*checkForInput[0] != *checkForInput[1])
-               return 0;
        }
        else
        {
            fd_set tmp_set;
+
+           if (*checkForInput[0] == *checkForInput[1]) {
+               if (timers)
+               {
+                    int expired = 0;
+                   now = GetTimeInMillis();
+                   if ((int) (timers->expires - now) <= 0)
+                       expired = 1;
+
+                   while (timers && (int) (timers->expires - now) <= 0)
+                       DoTimer(timers, now, &timers);
+
+                    if (expired)
+                        return 0;
+               }
+           }
 #ifdef SMART_SCHEDULE
            if (someReady)
                XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
@@ -646,3 +544,108 @@
        xfree(timer);
     }
 }
+
+static CARD32
+ScreenSaverTimeoutExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+    INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+    if (timeout < ScreenSaverTime) {
+        return ScreenSaverTime - timeout;
+    }
+
+    ResetOsBuffers(); /* not ideal, but better than nothing */
+    SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
+
+#ifdef DPMSExtension
+    if (ScreenSaverInterval > 0 && DPMSPowerLevel == DPMSModeOn)
+#else
+    if (ScreenSaverInterval > 0)
+#endif /* DPMSExtension */
+        return ScreenSaverInterval;
+
+    return 0;
+}
+
+static OsTimerPtr ScreenSaverTimer = NULL;
+
+void
+SetScreenSaverTimer(void)
+{
+    if (ScreenSaverTime > 0) {
+       ScreenSaverTimer = TimerSet(ScreenSaverTimer, 0, ScreenSaverTime,
+                                   ScreenSaverTimeoutExpire, NULL);
+    } else if (ScreenSaverTimer) {
+       TimerFree(ScreenSaverTimer);
+       ScreenSaverTimer = NULL;
+    }
+}
+
+#ifdef DPMSExtension
+
+static OsTimerPtr DPMSStandbyTimer = NULL;
+static OsTimerPtr DPMSSuspendTimer = NULL;
+static OsTimerPtr DPMSOffTimer = NULL;
+
+static CARD32
+DPMSStandbyTimerExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+    INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+    if (timeout < DPMSStandbyTime) {
+        return DPMSStandbyTime - timeout;
+    }
+    if (DPMSPowerLevel < DPMSModeStandby) {
+        DPMSSet(DPMSModeStandby);
+    }
+    return DPMSStandbyTime;
+}
+
+static CARD32
+DPMSSuspendTimerExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+    INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+    if (timeout < DPMSSuspendTime) {
+        return DPMSSuspendTime - timeout;
+    }
+    if (DPMSPowerLevel < DPMSModeSuspend) {
+        DPMSSet(DPMSModeSuspend);
+    }
+    return DPMSSuspendTime;
+}
+
+static CARD32
+DPMSOffTimerExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+    INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+    if (timeout < DPMSOffTime) {
+        return DPMSOffTime - timeout;
+    }
+    if (DPMSPowerLevel < DPMSModeOff) {
+        DPMSSet(DPMSModeOff);
+    }
+    return DPMSOffTime;
+}
+
+void
+SetDPMSTimers(void)
+{
+    if (!DPMSEnabled)
+        return;
+
+    if (DPMSStandbyTime > 0) {
+        DPMSStandbyTimer = TimerSet(DPMSStandbyTimer, 0, DPMSStandbyTime,
+                                    DPMSStandbyTimerExpire, NULL);
+    }
+    if (DPMSSuspendTime > 0) {
+        DPMSStandbyTimer = TimerSet(DPMSSuspendTimer, 0, DPMSSuspendTime,
+                                    DPMSSuspendTimerExpire, NULL);
+    }
+    if (DPMSOffTime > 0) {
+        DPMSOffTimer = TimerSet(DPMSOffTimer, 0, DPMSOffTime,
+                                DPMSOffTimerExpire, NULL);
+    }
+}
+#endif

Reply via email to