[gnome-online-accounts/gnome-3-10] 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-10] alarm: Check proper cancellable from timer source ready callback
- Date: Mon, 30 Sep 2013 09:23:16 +0000 (UTC)
commit 956fddf222209381ae2419788423344680f37af4
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 4b9d086..bcd5d53 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]