[evolution-data-server] Bug 695960 - Use a weak reference for GBusNameVanishedCallback



commit 98fb014dba84094ccb82356a7d6d5eb16b26bd59
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Mar 16 07:42:51 2013 -0400

    Bug 695960 - Use a weak reference for GBusNameVanishedCallback
    
    Similar to idle callbacks for signal emissions, the callback becomes a
    no-op if we lose the EClient.

 addressbook/libebook/e-book-client.c |   54 +++++++++++++++++++++++----------
 calendar/libecal/e-cal-client.c      |   54 +++++++++++++++++++++++----------
 2 files changed, 74 insertions(+), 34 deletions(-)
---
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 4497e55..b0baea5 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -162,6 +162,13 @@ run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
        g_slice_free (RunInThreadClosure, run_in_thread_closure);
 }
 
+static void
+weak_ref_free (GWeakRef *weak_ref)
+{
+       g_weak_ref_set (weak_ref, NULL);
+       g_slice_free (GWeakRef, weak_ref);
+}
+
 /*
  * Well-known book backend properties:
  * @BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS: Retrieves comma-separated list
@@ -455,27 +462,35 @@ book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
 static void
 book_client_name_vanished_cb (GDBusConnection *connection,
                               const gchar *name,
-                              EClient *client)
+                              GWeakRef *client_weak_ref)
 {
-       GSource *idle_source;
-       GMainContext *main_context;
-       SignalClosure *signal_closure;
+       EClient *client;
 
-       signal_closure = g_slice_new0 (SignalClosure);
-       g_weak_ref_set (&signal_closure->client, client);
+       client = g_weak_ref_get (client_weak_ref);
 
-       main_context = e_client_ref_main_context (client);
+       if (client != NULL) {
+               GSource *idle_source;
+               GMainContext *main_context;
+               SignalClosure *signal_closure;
 
-       idle_source = g_idle_source_new ();
-       g_source_set_callback (
-               idle_source,
-               book_client_emit_backend_died_idle_cb,
-               signal_closure,
-               (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, main_context);
-       g_source_unref (idle_source);
+               signal_closure = g_slice_new0 (SignalClosure);
+               g_weak_ref_set (&signal_closure->client, client);
 
-       g_main_context_unref (main_context);
+               main_context = e_client_ref_main_context (client);
+
+               idle_source = g_idle_source_new ();
+               g_source_set_callback (
+                       idle_source,
+                       book_client_emit_backend_died_idle_cb,
+                       signal_closure,
+                       (GDestroyNotify) signal_closure_free);
+               g_source_attach (idle_source, main_context);
+               g_source_unref (idle_source);
+
+               g_main_context_unref (main_context);
+
+               g_object_unref (client);
+       }
 }
 
 static void
@@ -702,6 +717,7 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
        EDBusAddressBookFactory *factory_proxy;
        GDBusConnection *connection;
        GDBusProxy *proxy;
+       GWeakRef *weak_ref;
        EClient *client;
        ESource *source;
        const gchar *uid;
@@ -786,13 +802,17 @@ book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
 
        g_dbus_proxy_set_default_timeout (proxy, DBUS_PROXY_TIMEOUT_MS);
 
+       /* XXX Wishing for g_weak_ref_new() / g_weak_ref_free() here. */
+       weak_ref = g_slice_new0 (GWeakRef);
+       g_weak_ref_set (weak_ref, client);
+
        priv->name_watcher_id = g_bus_watch_name_on_connection (
                connection,
                g_dbus_proxy_get_name (proxy),
                G_BUS_NAME_WATCHER_FLAGS_NONE,
                (GBusNameAppearedCallback) NULL,
                (GBusNameVanishedCallback) book_client_name_vanished_cb,
-               client, (GDestroyNotify) NULL);
+               weak_ref, (GDestroyNotify) weak_ref_free);
 
        handler_id = g_signal_connect_object (
                proxy, "error",
diff --git a/calendar/libecal/e-cal-client.c b/calendar/libecal/e-cal-client.c
index 784e968..bd85c50 100644
--- a/calendar/libecal/e-cal-client.c
+++ b/calendar/libecal/e-cal-client.c
@@ -217,6 +217,13 @@ run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
 }
 
 static void
+weak_ref_free (GWeakRef *weak_ref)
+{
+       g_weak_ref_set (weak_ref, NULL);
+       g_slice_free (GWeakRef, weak_ref);
+}
+
+static void
 free_zone_cb (gpointer zone)
 {
        icaltimezone_free (zone, 1);
@@ -672,27 +679,35 @@ cal_client_dbus_proxy_free_busy_data_cb (EDBusCalendar *dbus_proxy,
 static void
 cal_client_name_vanished_cb (GDBusConnection *connection,
                              const gchar *name,
-                             EClient *client)
+                             GWeakRef *client_weak_ref)
 {
-       GSource *idle_source;
-       GMainContext *main_context;
-       SignalClosure *signal_closure;
+       EClient *client;
 
-       signal_closure = g_slice_new0 (SignalClosure);
-       g_weak_ref_set (&signal_closure->client, client);
+       client = g_weak_ref_get (client_weak_ref);
 
-       main_context = e_client_ref_main_context (client);
+       if (client != NULL) {
+               GSource *idle_source;
+               GMainContext *main_context;
+               SignalClosure *signal_closure;
 
-       idle_source = g_idle_source_new ();
-       g_source_set_callback (
-               idle_source,
-               cal_client_emit_backend_died_idle_cb,
-               signal_closure,
-               (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, main_context);
-       g_source_unref (idle_source);
+               signal_closure = g_slice_new0 (SignalClosure);
+               g_weak_ref_set (&signal_closure->client, client);
 
-       g_main_context_unref (main_context);
+               main_context = e_client_ref_main_context (client);
+
+               idle_source = g_idle_source_new ();
+               g_source_set_callback (
+                       idle_source,
+                       cal_client_emit_backend_died_idle_cb,
+                       signal_closure,
+                       (GDestroyNotify) signal_closure_free);
+               g_source_attach (idle_source, main_context);
+               g_source_unref (idle_source);
+
+               g_main_context_unref (main_context);
+
+               g_object_unref (client);
+       }
 }
 
 static void
@@ -979,6 +994,7 @@ cal_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
        EDBusCalendarFactory *factory_proxy;
        GDBusConnection *connection;
        GDBusProxy *proxy;
+       GWeakRef *weak_ref;
        EClient *client;
        ESource *source;
        const gchar *uid;
@@ -1080,13 +1096,17 @@ cal_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
 
        g_dbus_proxy_set_default_timeout (proxy, DBUS_PROXY_TIMEOUT_MS);
 
+       /* XXX Wishing for g_weak_ref_new() / g_weak_ref_free() here. */
+       weak_ref = g_slice_new0 (GWeakRef);
+       g_weak_ref_set (weak_ref, client);
+
        priv->name_watcher_id = g_bus_watch_name_on_connection (
                connection,
                g_dbus_proxy_get_name (proxy),
                G_BUS_NAME_WATCHER_FLAGS_NONE,
                (GBusNameAppearedCallback) NULL,
                (GBusNameVanishedCallback) cal_client_name_vanished_cb,
-               client, (GDestroyNotify) NULL);
+               weak_ref, (GDestroyNotify) weak_ref_free);
 
        handler_id = g_signal_connect_object (
                proxy, "error",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]