[PATCH] sync: fix corner-case in triggering idle alarms

Peter Hutterer peter.hutterer at who-t.net
Wed Oct 30 07:26:05 CET 2013

ProcessInputEvent() resets the device idle times. If idle time was higher than
the lower bracket, this should trigger an event in the idle time wakeup

If processing is slow, the idle time may advance past the lower bracket
between the reset and the time the BlockHandler is called. In that case, we'd
never schedule a wakeup to handle the event, causing us to randomly miss

Ran tests with a neg transition trigger on 5ms with 200 repeats of the test
and it succeeded. Anything below that gets a bit tricky to make sure the
server sees the same idle time as the client usleeps for.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
 Xext/sync.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index b2ee92e..53f769d 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2654,7 +2654,16 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
     IdleTimeQueryValue(counter, &idle);
     counter->value = idle;      /* push, so CheckTrigger works */
-    if (less && XSyncValueLessOrEqual(idle, *less)) {
+    /**
+     * There's an indefinite amount of time between ProcessInputEvents()
+     * where the idle time is reset and the time we actually get here. idle
+     * may be past the lower bracket if we dawdled with the events, so
+     * check for whether we did reset and bomb out of select immediately.
+     */
+    if (less && XSyncValueGreaterThan(idle, *less) &&
+        LastEventTimeWasReset(priv->deviceid)) {
+        AdjustWaitForDelay(wt, 0);
+    } else if (less && XSyncValueLessOrEqual(idle, *less)) {
          * We've been idle for less than the threshold value, and someone
          * wants to know about that, but now we need to know whether they

More information about the xorg-devel mailing list