[gnome-power-manager] Avoid a race in detecting the idle reset alarm
- From: Richard Hughes <rhughes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-power-manager] Avoid a race in detecting the idle reset alarm
- Date: Fri, 12 Feb 2010 14:34:46 +0000 (UTC)
commit 7380ab4e13db76cb5be2e1bc4a42a810a5261fd4
Author: Chris Coulson <chrisccoulson googlemail com>
Date: Fri Feb 12 02:47:15 2010 +0000
Avoid a race in detecting 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 creates a reset alarm when creating a EggIdletime
instance, but blocks emitting a "reset" signal from this instance
each time the reset alarm expires, unless the idle timeout alarm
has triggered since the last time the reset alarm expired. This
ensures that we always catch the reset alarm.
src/egg-idletime.c | 42 ++++++++++--------------------------------
1 files changed, 10 insertions(+), 32 deletions(-)
---
diff --git a/src/egg-idletime.c b/src/egg-idletime.c
index 2145eac..64aa380 100644
--- a/src/egg-idletime.c
+++ b/src/egg-idletime.c
@@ -146,16 +146,15 @@ 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);
egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_POSITIVE);
}
- /* set the reset alarm to be disabled */
- alarm = g_ptr_array_index (idletime->priv->array, 0);
- egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_DISABLED);
-
/* emit signal so say we've reset all timers */
g_signal_emit (idletime, signals [SIGNAL_RESET], 0);
@@ -180,33 +179,6 @@ egg_idletime_alarm_find_id (EggIdletime *idletime, guint id)
}
/**
- * egg_idletime_set_reset_alarm:
- */
-static void
-egg_idletime_set_reset_alarm (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
-{
- EggIdletimeAlarm *alarm;
- int overflow;
- XSyncValue add;
-
- alarm = egg_idletime_alarm_find_id (idletime, 0);
-
- if (!idletime->priv->reset_set) {
- /* don't match on the current value because
- * XSyncNegativeComparison means less or equal. */
- XSyncIntToValue (&add, -1);
- XSyncValueAdd (&alarm->timeout, alarm_event->counter_value, add, &overflow);
-
- /* set the reset alarm to fire the next time
- * idletime->priv->idle_counter < the current counter value */
- egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_NEGATIVE);
-
- /* don't try to set this again if multiple timers are going off in sequence */
- idletime->priv->reset_set = TRUE;
- }
-}
-
-/**
* egg_idletime_alarm_find_event:
*/
static EggIdletimeAlarm *
@@ -254,7 +226,7 @@ egg_idletime_event_filter_cb (GdkXEvent *gdkxevent, GdkEvent *event, gpointer da
g_signal_emit (alarm->idletime, signals [SIGNAL_ALARM_EXPIRED], 0, alarm->id);
/* we need the first alarm to go off to set the reset alarm */
- egg_idletime_set_reset_alarm (idletime, alarm_event);
+ idletime->priv->reset_set = TRUE;
out:
/* don't propagate */
return GDK_FILTER_REMOVE;
@@ -416,6 +388,12 @@ egg_idletime_init (EggIdletime *idletime)
/* create a reset alarm */
alarm = egg_idletime_alarm_new (idletime, 0);
g_ptr_array_add (idletime->priv->array, alarm);
+
+ XSyncIntToValue (&alarm->timeout, 0);
+
+ /* set the reset alarm to fire when the
+ * idle_counter == 0 */
+ egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_NEGATIVE);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]