[gnome-online-accounts/gnome-3-8] alarm: Check proper cancellable from timer source ready callback
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/gnome-3-8] alarm: Check proper cancellable from timer source ready callback
- Date: Mon, 30 Sep 2013 09:24:48 +0000 (UTC)
commit f3052079ab680dfe0008d3b21f3b83f100e5445e
Author: Ray Strode <rstrode redhat com>
Date: Fri Sep 27 21:02:11 2013 -0400
alarm: Check proper cancellable from timer source ready callback
on_timer_source_ready is called in two cases:
1) When the timer fires
2) When the input stream cancellable is cancelled
We attempt to check for this latter case up front at the start of the
function and react appropriately. We do this by checking if
self->priv->cancellable is cancelled.
Unforunately, checking self->priv->cancellable isn't always right,
because self->priv->cancellable isn't always the cancellable associated
with the input stream. They can get out of sync, when for instance, the
alarm expiration time is changed. In this case the old input stream
cancellable will get cancelled, and self->priv->cancellable will get set
to the new cancellable.
This commit makes sure the on_timer_source_ready callback always checks
the cancellable associated with the input stream. It accomplishes this
by allocating a GTask and using that as the callback data instead of
the alarm object directly.
https://bugzilla.gnome.org/show_bug.cgi?id=708975
src/goaidentity/goaalarm.c | 23 ++++++++++++++++++-----
1 files changed, 18 insertions(+), 5 deletions(-)
---
diff --git a/src/goaidentity/goaalarm.c b/src/goaidentity/goaalarm.c
index 05160af..afcb9d6 100644
--- a/src/goaidentity/goaalarm.c
+++ b/src/goaidentity/goaalarm.c
@@ -359,18 +359,23 @@ out:
#ifdef HAVE_TIMERFD
static gboolean
-on_timer_source_ready (GObject *stream, GoaAlarm *self)
+on_timer_source_ready (GObject *stream, GTask *task)
{
gint64 number_of_fires;
gssize bytes_read;
gboolean run_again = FALSE;
GError *error = NULL;
+ GoaAlarm *self;
+ GCancellable *cancellable;
+
+ self = g_task_get_source_object (task);
+ cancellable = g_task_get_cancellable (task);
g_return_val_if_fail (GOA_IS_ALARM (self), FALSE);
g_return_val_if_fail (self->priv->type == GOA_ALARM_TYPE_TIMER, FALSE);
g_rec_mutex_lock (&self->priv->lock);
- if (g_cancellable_is_cancelled (self->priv->cancellable))
+ if (g_cancellable_is_cancelled (cancellable))
goto out;
bytes_read =
@@ -403,9 +408,14 @@ out:
}
static void
-clear_timer_source_pointer (GoaAlarm *self)
+clear_timer_source (GTask *task)
{
+ GoaAlarm *self;
+
+ self = g_task_get_source_object (task);
self->priv->timer.source = NULL;
+
+ g_object_unref (task);
}
#endif
@@ -417,6 +427,7 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
int fd;
int result;
GSource *source;
+ GTask *task;
static gboolean seen_before = FALSE;
if (!seen_before)
@@ -449,14 +460,16 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
self->priv->type = GOA_ALARM_TYPE_TIMER;
self->priv->timer.stream = g_unix_input_stream_new (fd, TRUE);
+ task = g_task_new (self, self->priv->cancellable, NULL, NULL);
+
source =
g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM
(self->priv->timer.stream),
self->priv->cancellable);
self->priv->timer.source = source;
g_source_set_callback (self->priv->timer.source,
- (GSourceFunc) on_timer_source_ready, self,
- (GDestroyNotify) clear_timer_source_pointer);
+ (GSourceFunc) on_timer_source_ready, task,
+ (GDestroyNotify) clear_timer_source);
g_source_attach (self->priv->timer.source, self->priv->context);
g_source_unref (source);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]