[gnome-online-accounts/gnome-3-8] goaidentity: Fix deadlock in goaalarm on_cancelled
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/gnome-3-8] goaidentity: Fix deadlock in goaalarm on_cancelled
- Date: Wed, 28 Aug 2013 15:33:26 +0000 (UTC)
commit 88eecb0f1ae8510d569ece56090bcebc5ab65cf7
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 c8992cd..9ccb3b6 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]