[gnome-online-accounts/rhel-7.1: 19/34] alarm: Tag the "cancelled" handler with the correct source and stream



commit 8f19e2a5649ee0b0b2d56d8392b4a12e09f62c5f
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Nov 11 13:11:28 2013 +0100

    alarm: Tag the "cancelled" handler with the correct source and stream
    
    When a time is set using goa_alarm_set_time, we try to clear the older
    source and stream by cancelling self->priv->cancellable. However,
    before we have had a chance to actually clear them in an idle callback,
    a new source and stream corresponding to the new time is set. This
    causes the older source and stream to be leaked, and instead the newly
    created objects are cleared.
    
    This is wrong. To set things right, we tag the cancelled handler with
    the older source and stream before they are overwritten.
    
    Fixes: https://bugzilla.gnome.org/711696

 src/goaidentity/goaalarm.c |   60 +++++++++++++++++++++++++------------------
 1 files changed, 35 insertions(+), 25 deletions(-)
---
diff --git a/src/goaidentity/goaalarm.c b/src/goaidentity/goaalarm.c
index f5a1dfb..68a6c46 100644
--- a/src/goaidentity/goaalarm.c
+++ b/src/goaidentity/goaalarm.c
@@ -90,16 +90,16 @@ clear_scheduled_immediate_wakeup (GoaAlarm *self)
 }
 
 static void
-clear_scheduled_timer_wakeups (GoaAlarm *self)
+clear_scheduled_timer_wakeups (GoaAlarm *self, GSource *source, GInputStream *stream)
 {
 #ifdef HAVE_TIMERFD
   GError *error;
   gboolean is_closed;
 
-  g_clear_pointer (&self->priv->scheduled_wakeup_source, (GDestroyNotify) g_source_destroy);
+  g_source_destroy (source);
 
   error = NULL;
-  is_closed = g_input_stream_close (self->priv->stream, NULL, &error);
+  is_closed = g_input_stream_close (stream, NULL, &error);
 
   if (!is_closed)
     {
@@ -107,18 +107,18 @@ clear_scheduled_timer_wakeups (GoaAlarm *self)
       g_error_free (error);
     }
 
-  g_clear_object (&self->priv->stream);
+  g_object_unref (stream);
 #endif
 }
 
 static void
-clear_scheduled_timeout_wakeups (GoaAlarm *self)
+clear_scheduled_timeout_wakeups (GoaAlarm *self, GSource *source)
 {
-  g_clear_pointer (&self->priv->scheduled_wakeup_source, (GDestroyNotify) g_source_destroy);
+  g_source_destroy (source);
 }
 
 static void
-clear_scheduled_wakeups (GoaAlarm *self)
+clear_scheduled_wakeups (GoaAlarm *self, GSource *source, GInputStream *stream)
 {
   g_rec_mutex_lock (&self->priv->lock);
   clear_scheduled_immediate_wakeup (self);
@@ -126,11 +126,11 @@ clear_scheduled_wakeups (GoaAlarm *self)
   switch (self->priv->type)
     {
     case GOA_ALARM_TYPE_TIMER:
-      clear_scheduled_timer_wakeups (self);
+      clear_scheduled_timer_wakeups (self, source, stream);
       break;
 
     case GOA_ALARM_TYPE_TIMEOUT:
-      clear_scheduled_timeout_wakeups (self);
+      clear_scheduled_timeout_wakeups (self, source);
       break;
 
     default:
@@ -161,7 +161,7 @@ goa_alarm_finalize (GObject *object)
 {
   GoaAlarm *self = GOA_ALARM (object);
 
-  clear_scheduled_wakeups (self);
+  clear_scheduled_wakeups (self, self->priv->scheduled_wakeup_source, self->priv->stream);
 
   g_rec_mutex_clear (&self->priv->lock);
 
@@ -252,9 +252,18 @@ goa_alarm_init (GoaAlarm *self)
 static gboolean
 async_alarm_cancel_idle_cb (gpointer user_data)
 {
-  GoaAlarm *self = user_data;
+  GoaAlarm *self;
+  GInputStream *stream;
+  GSource *source;
+  GTask *task = G_TASK (user_data);
+  gpointer task_data;
 
-  clear_scheduled_wakeups (self);
+  self = g_task_get_source_object (task);
+  source = (GSource *) g_object_get_data (G_OBJECT (task), "alarm-scheduled-wakeup-source");
+  task_data = g_object_get_data (G_OBJECT (task), "alarm-stream");
+  stream = (task_data == NULL) ? NULL : G_INPUT_STREAM (task_data);
+
+  clear_scheduled_wakeups (self, source, stream);
   return G_SOURCE_REMOVE;
 }
 
@@ -263,13 +272,25 @@ on_cancelled (GCancellable *cancellable, gpointer user_data)
 {
   GoaAlarm *self = GOA_ALARM (user_data);
   GSource *idle_source;
+  GTask *task;
 
+  task = g_task_new (self, NULL, NULL, NULL);
+
+  g_object_set_data_full (G_OBJECT (task),
+                          "alarm-scheduled-wakeup-source",
+                          g_source_ref (self->priv->scheduled_wakeup_source),
+                          (GDestroyNotify) g_source_unref);
+
+  if (self->priv->stream != NULL)
+    g_object_set_data_full (G_OBJECT (task), "alarm-stream", g_object_ref (self->priv->stream), 
g_object_unref);
 
   idle_source = g_idle_source_new ();
   g_source_set_priority (idle_source, G_PRIORITY_HIGH_IDLE);
-  g_source_set_callback (idle_source, async_alarm_cancel_idle_cb, g_object_ref (self), g_object_unref);
+  g_source_set_callback (idle_source, async_alarm_cancel_idle_cb, g_object_ref (task), g_object_unref);
   g_source_attach (idle_source, self->priv->context);
   g_source_unref (idle_source);
+
+  g_object_unref (task);
 }
 
 static void
@@ -414,17 +435,6 @@ out:
   g_rec_mutex_unlock (&self->priv->lock);
   return run_again;
 }
-
-static void
-clear_timer_source (GTask *task)
-{
-  GoaAlarm *self;
-
-  self = g_task_get_source_object (task);
-  self->priv->scheduled_wakeup_source = NULL;
-
-  g_object_unref (task);
-}
 #endif
 
 static gboolean
@@ -477,7 +487,7 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
   self->priv->scheduled_wakeup_source = source;
   g_source_set_callback (self->priv->scheduled_wakeup_source,
                          (GSourceFunc) on_timer_source_ready, task,
-                         (GDestroyNotify) clear_timer_source);
+                         (GDestroyNotify) g_object_unref);
   g_source_attach (self->priv->scheduled_wakeup_source, self->priv->context);
   g_source_unref (source);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]