[gnome-online-accounts/rhel-7.1: 19/34] alarm: Tag the "cancelled" handler with the correct source and stream
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/rhel-7.1: 19/34] alarm: Tag the "cancelled" handler with the correct source and stream
- Date: Mon, 4 Aug 2014 13:43:32 +0000 (UTC)
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]