ESourceRefresh: Handle "notify" signals from an idle callback.
authorMatthew Barnes <mbarnes@redhat.com>
Wed, 6 Jun 2012 17:15:08 +0000 (13:15 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Wed, 6 Jun 2012 17:15:08 +0000 (13:15 -0400)
ESourceRefresh runs e_source_refresh_force_timeout() in response to its
ESource becoming enabled.  The problem is "GObject::notify" signals can
be emitted from any thread.

Schedule an idle callback on the ESource's GMainContext to call
e_source_refresh_force_timeout(), rather than calling it directly from
the "GObject::notify" signal handler.

libedataserver/e-source-refresh.c

index 8c0e493..8ed2576 100644 (file)
@@ -191,13 +191,37 @@ source_refresh_update_timeouts (ESourceRefresh *extension,
        g_mutex_unlock (extension->priv->timeout_lock);
 }
 
+static gboolean
+source_refresh_idle_cb (gpointer user_data)
+{
+       ESource *source = E_SOURCE (user_data);
+
+       if (e_source_get_enabled (source))
+               e_source_refresh_force_timeout (source);
+
+       return FALSE;
+}
+
 static void
 source_refresh_notify_enabled_cb (ESource *source,
                                   GParamSpec *pspec,
                                   ESourceRefresh *extension)
 {
-       if (e_source_get_enabled (source))
-               e_source_refresh_force_timeout (source);
+       GSource *idle_source;
+       GMainContext *main_context;
+
+       main_context = e_source_ref_main_context (source);
+
+       idle_source = g_idle_source_new ();
+       g_source_set_callback (
+               idle_source,
+               source_refresh_idle_cb,
+               g_object_ref (source),
+               (GDestroyNotify) g_object_unref);
+       g_source_attach (idle_source, main_context);
+       g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void