diff options
| author | Chris Coulson <chrisccoulson@googlemail.com> | 2010-03-17 10:52:45 (GMT) |
|---|---|---|
| committer | Chris Coulson <chrisccoulson@googlemail.com> | 2010-03-17 10:59:45 (GMT) |
| commit | 0c171b962989d20b55f65ae016c584d3543f4801 (patch) | |
| tree | 03ba2a5f9bbee83749fb0d373e898b2a20d20e47 | |
| parent | 487fb08873d425b4afd339ba2019916b99186e4e (diff) | |
| download | gnome-power-manager-0c171b962989d20b55f65ae016c584d3543f4801.zip gnome-power-manager-0c171b962989d20b55f65ae016c584d3543f4801.tar.xz | |
Fix a race condition where we can miss the idle reset alarm
When the idle timeout alarm fires, a reset alarm is created. If the IDLETIME counter resets in between the idle timeout alarm being detected and creating the reset alarm, then the reset alarm will be missed and we will think that X is idle forever.
This patch checks the current IDLETIME value from the server just after creating the reset alarm. If the current value is less than the reset threshold, then we assume that we missed the event and handle it accordingly.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=609720
| -rw-r--r-- | src/egg-idletime.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/egg-idletime.c b/src/egg-idletime.c index 2145eac..a18e8d1 100644 --- a/src/egg-idletime.c +++ b/src/egg-idletime.c @@ -146,6 +146,9 @@ egg_idletime_alarm_reset_all (EggIdletime *idletime) g_return_if_fail (EGG_IS_IDLETIME (idletime)); + if (!idletime->priv->reset_set) + return; + /* reset all the alarms (except the reset alarm) to their timeouts */ for (i=1; i<idletime->priv->array->len; i++) { alarm = g_ptr_array_index (idletime->priv->array, i); @@ -188,6 +191,7 @@ egg_idletime_set_reset_alarm (EggIdletime *idletime, XSyncAlarmNotifyEvent *alar EggIdletimeAlarm *alarm; int overflow; XSyncValue add; + gint64 current, reset_threshold; alarm = egg_idletime_alarm_find_id (idletime, 0); @@ -203,6 +207,13 @@ egg_idletime_set_reset_alarm (EggIdletime *idletime, XSyncAlarmNotifyEvent *alar /* don't try to set this again if multiple timers are going off in sequence */ idletime->priv->reset_set = TRUE; + + current = egg_idletime_get_time (idletime); + reset_threshold = egg_idletime_xsyncvalue_to_int64 (alarm->timeout); + if (current < reset_threshold) { + /* We've missed the alarm already */ + egg_idletime_alarm_reset_all (idletime); + } } } |