[gnome-power-manager] Avoid a race in detecting the idle reset alarm



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]