aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-02-21 03:52:43 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-02-21 05:35:58 +0800
commitc941bab5240f951bccbaff6d3836333a29b16e2d (patch)
tree37428a4e56e540f1dc92d459ec13793e9d922522
parent1abd497f66baa3fe278fdb02f2a85be27d5dd86e (diff)
downloadgsoc2013-evolution-c941bab5240f951bccbaff6d3836333a29b16e2d.tar.gz
gsoc2013-evolution-c941bab5240f951bccbaff6d3836333a29b16e2d.tar.zst
gsoc2013-evolution-c941bab5240f951bccbaff6d3836333a29b16e2d.zip
EClientCache: Don't emit signals while holding a lock.
Jeez, I should know this by now. Schedule an idle callback on the internal GMainContext to emit the signal like we do for other signals.
-rw-r--r--e-util/e-client-cache.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/e-util/e-client-cache.c b/e-util/e-client-cache.c
index b1d9dcfc10..3709104d09 100644
--- a/e-util/e-client-cache.c
+++ b/e-util/e-client-cache.c
@@ -371,6 +371,19 @@ client_cache_emit_client_notify_idle_cb (gpointer user_data)
return FALSE;
}
+static gboolean
+client_cache_emit_client_created_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->cache,
+ signals[CLIENT_CREATED], 0,
+ signal_closure->client);
+
+ return FALSE;
+}
+
static void
client_cache_backend_died_cb (EClient *client,
ClientData *client_data)
@@ -489,6 +502,8 @@ client_cache_process_results (ClientData *client_data,
/* If the EClientCache has been disposed already,
* there's no point in connecting signal handlers. */
if (cache != NULL) {
+ GSource *idle_source;
+ SignalClosure *signal_closure;
gulong handler_id;
/* client_data_dispose() will break the
@@ -518,8 +533,19 @@ client_cache_process_results (ClientData *client_data,
0);
client_data->notify_handler_id = handler_id;
- g_signal_emit (
- cache, signals[CLIENT_CREATED], 0, client);
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->cache = g_object_ref (cache);
+ signal_closure->client = g_object_ref (client);
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ client_cache_emit_client_created_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (
+ idle_source, cache->priv->main_context);
+ g_source_unref (idle_source);
g_object_unref (cache);
}