[gnome-online-accounts] goaidentity: Fix deadlock in goaalarm on_cancelled
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts] goaidentity: Fix deadlock in goaalarm on_cancelled
- Date: Wed, 28 Aug 2013 15:31:51 +0000 (UTC)
commit f4c04ad49c29d8f619cb80ef480daa9d4ecdfa38
Author: Alban Browaeys <prahal yahoo com>
Date: Sat Aug 3 12:34:07 2013 +0200
goaidentity: Fix deadlock in goaalarm on_cancelled
Calling g_cancellable_disconnect in a cancelled handler causes a
deadlock. This happens here as in clear_scheduled_timer_wakeups we
destroy the cancellable source that emitted the cancelled signal.
(goaalarm: on_cancelled-> clear_scheduled_wakeups
-> clear_scheduled_timer_wakeups -> g_source_destroy
-> g_source_destroy_internal -> g_child_source_remove_internal
-> g_source_unref_internal -> cancellable_source_finalize
-> g_cancellable_disconnect).
Thus based on Matthew Barnes , evolution commit
c155b170bcf644ab2cdf7b11afdda0d9c100772e :
EPhotoCache: Fix deadlock when cancelling subtasks.
That is, we move the cancelled task into the main thread in an idle
source, to prevent the disconnect from happening inside the cancelled
handler.
Fixes: https://bugzilla.gnome.org/705395
src/goaidentity/goaalarm.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
---
diff --git a/src/goaidentity/goaalarm.c b/src/goaidentity/goaalarm.c
index 79e2a12..ae749f7 100644
--- a/src/goaidentity/goaalarm.c
+++ b/src/goaidentity/goaalarm.c
@@ -256,12 +256,31 @@ goa_alarm_init (GoaAlarm *self)
g_rec_mutex_init (&self->priv->lock);
}
+static gboolean
+async_alarm_cancel_idle_cb (gpointer user_data)
+{
+ GoaAlarm *self = user_data;
+
+ clear_scheduled_wakeups (self);
+ return G_SOURCE_REMOVE;
+}
+
static void
on_cancelled (GCancellable *cancellable, gpointer user_data)
{
GoaAlarm *self = GOA_ALARM (user_data);
+ GMainContext *main_context;
+ GSource *idle_source;
- clear_scheduled_wakeups (self);
+ main_context = g_main_context_ref_thread_default ();
+
+ 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_attach (idle_source, main_context);
+ g_source_unref (idle_source);
+
+ g_main_context_unref (main_context);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]