diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-10-16 10:08:46 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-10-18 16:44:32 +1000 |
commit | 06b87aa528d7a739ba20101a1f83b1a428691a01 (patch) | |
tree | 3bc098f953e43cb6177300b63c6059651ba08cbd /dix | |
parent | efc1035ca958f2c9d266338a308518a0834b1773 (diff) |
sync: if the idle time was reset, force alarms to trigger (#70476)
The time between the idle reset and the IdleTimeWakeupHandler to be called is
indeterminate. Clients with an PositiveTransition or NegativeTransition alarm
on a low threshold may miss an alarm.
Work around this by keeping a reset flag for each device. When the
WakeupHandler triggers and the reset flag is set, we force a re-calculation of
everything and pretend the current idle time is zero. Immediately after is the
next calculation with the real idle time.
Relatively reproducible test case: Set up a XSyncNegativeTransition alarm for
a threshold of 1 ms. May trigger, may not.
X.Org Bug 70476 <http://bugs.freedesktop.org/show_bug.cgi?id=70476>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'dix')
-rw-r--r-- | dix/events.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/dix/events.c b/dix/events.c index c803721f3..4632bb7db 100644 --- a/dix/events.c +++ b/dix/events.c @@ -262,7 +262,10 @@ InputInfo inputInfo; EventSyncInfoRec syncEvents; -static TimeStamp lastDeviceEventTime[MAXDEVICES]; +static struct DeviceEventTime { + Bool reset; + TimeStamp time; +} lastDeviceEventTime[MAXDEVICES]; /** * The root window the given device is currently on. @@ -1060,8 +1063,11 @@ MonthChangedOrBadTime(CARD32 *ms) void NoticeTime(const DeviceIntPtr dev, TimeStamp time) { - lastDeviceEventTime[XIAllDevices] = currentTime; - lastDeviceEventTime[dev->id] = currentTime; + lastDeviceEventTime[XIAllDevices].time = currentTime; + lastDeviceEventTime[dev->id].time = currentTime; + + LastEventTimeToggleResetFlag(dev->id, TRUE); + LastEventTimeToggleResetFlag(XIAllDevices, TRUE); } static void @@ -1085,7 +1091,30 @@ NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) TimeStamp LastEventTime(int deviceid) { - return lastDeviceEventTime[deviceid]; + return lastDeviceEventTime[deviceid].time; +} + +Bool +LastEventTimeWasReset(int deviceid) +{ + return lastDeviceEventTime[deviceid].reset; +} + +void +LastEventTimeToggleResetFlag(int deviceid, Bool state) +{ + lastDeviceEventTime[deviceid].reset = state; +} + +void +LastEventTimeToggleResetAll(Bool state) +{ + DeviceIntPtr dev; + nt_list_for_each_entry(dev, inputInfo.devices, next) { + LastEventTimeToggleResetFlag(dev->id, FALSE); + } + LastEventTimeToggleResetFlag(XIAllDevices, FALSE); + LastEventTimeToggleResetFlag(XIAllMasterDevices, FALSE); } /************************************************************************** @@ -5297,6 +5326,7 @@ InitEvents(void) dummy.id = i; NoticeTime(&dummy, currentTime); + LastEventTimeToggleResetFlag(i, FALSE); } syncEvents.replayDev = (DeviceIntPtr) NULL; |