[evolution-data-server] EClient: Add a read-only "main-context" property.



commit 5b8dd5068531dfb7ad97619ad94a1df8b97b8673
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sat Feb 23 10:16:56 2013 -0500

    EClient: Add a read-only "main-context" property.
    
    This is the GMainContext on which to attach client event sources.
    
    New functions:
    
        e_client_ref_main_context()

 addressbook/libebook/e-book-client.c               |   49 ++++++++-------
 calendar/libecal/e-cal-client.c                    |   67 ++++++++++++--------
 .../libedataserver/libedataserver-sections.txt     |    1 +
 libedataserver/e-client.c                          |   49 ++++++++++++++
 libedataserver/e-client.h                          |    1 +
 5 files changed, 119 insertions(+), 48 deletions(-)
---
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 3560456..6d8bef7 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -53,7 +53,6 @@ typedef struct _ConnectClosure ConnectClosure;
 typedef struct _RunInThreadClosure RunInThreadClosure;
 
 struct _EBookClientPrivate {
-       GMainContext *main_context;
        EDBusAddressBook *dbus_proxy;
        EDataBook *direct_book;
        guint name_watcher_id;
@@ -457,29 +456,34 @@ book_client_emit_backend_property_changed_idle_cb (gpointer user_data)
 static void
 book_client_dbus_proxy_error_cb (EDBusAddressBook *dbus_proxy,
                                  const gchar *error_message,
-                                 EBookClient *book_client)
+                                 EClient *client)
 {
        GSource *idle_source;
+       GMainContext *main_context;
        SignalClosure *signal_closure;
 
        signal_closure = g_slice_new0 (SignalClosure);
-       signal_closure->client = g_object_ref (book_client);
+       signal_closure->client = g_object_ref (client);
        signal_closure->error_message = g_strdup (error_message);
 
+       main_context = e_client_ref_main_context (client);
+
        idle_source = g_idle_source_new ();
        g_source_set_callback (
                idle_source,
                book_client_emit_backend_error_idle_cb,
                signal_closure,
                (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, book_client->priv->main_context);
+       g_source_attach (idle_source, main_context);
        g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void
 book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
                                   GParamSpec *pspec,
-                                  EBookClient *book_client)
+                                  EClient *client)
 {
        const gchar *backend_prop_name = NULL;
 
@@ -498,7 +502,7 @@ book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
                        csv = g_strjoinv (",", strv);
                        g_strfreev (strv);
                }
-               e_client_set_capabilities (E_CLIENT (book_client), csv);
+               e_client_set_capabilities (client, csv);
                g_free (csv);
        }
 
@@ -508,7 +512,7 @@ book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
                backend_prop_name = CLIENT_BACKEND_PROPERTY_ONLINE;
 
                online = e_dbus_address_book_get_online (dbus_proxy);
-               e_client_set_online (E_CLIENT (book_client), online);
+               e_client_set_online (client, online);
        }
 
        if (g_str_equal (pspec->name, "required-fields")) {
@@ -529,38 +533,46 @@ book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
                backend_prop_name = CLIENT_BACKEND_PROPERTY_READONLY;
 
                writable = e_dbus_address_book_get_writable (dbus_proxy);
-               e_client_set_readonly (E_CLIENT (book_client), !writable);
+               e_client_set_readonly (client, !writable);
        }
 
        if (backend_prop_name != NULL) {
                GSource *idle_source;
+               GMainContext *main_context;
                SignalClosure *signal_closure;
 
                signal_closure = g_slice_new0 (SignalClosure);
-               signal_closure->client = g_object_ref (book_client);
+               signal_closure->client = g_object_ref (client);
                signal_closure->property_name = g_strdup (backend_prop_name);
 
+               main_context = e_client_ref_main_context (client);
+
                idle_source = g_idle_source_new ();
                g_source_set_callback (
                        idle_source,
                        book_client_emit_backend_property_changed_idle_cb,
                        signal_closure,
                        (GDestroyNotify) signal_closure_free);
-               g_source_attach (idle_source, book_client->priv->main_context);
+               g_source_attach (idle_source, main_context);
                g_source_unref (idle_source);
+
+               g_main_context_unref (main_context);
        }
 }
 
 static void
 book_client_name_vanished_cb (GDBusConnection *connection,
                               const gchar *name,
-                              EBookClient *book_client)
+                              EClient *client)
 {
        GSource *idle_source;
+       GMainContext *main_context;
        SignalClosure *signal_closure;
 
        signal_closure = g_slice_new0 (SignalClosure);
-       signal_closure->client = g_object_ref (book_client);
+       signal_closure->client = g_object_ref (client);
+
+       main_context = e_client_ref_main_context (client);
 
        idle_source = g_idle_source_new ();
        g_source_set_callback (
@@ -568,8 +580,10 @@ book_client_name_vanished_cb (GDBusConnection *connection,
                book_client_emit_backend_died_idle_cb,
                signal_closure,
                (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, book_client->priv->main_context);
+       g_source_attach (idle_source, main_context);
        g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void
@@ -621,11 +635,6 @@ book_client_dispose (GObject *object)
                priv->dbus_proxy = NULL;
        }
 
-       if (priv->main_context != NULL) {
-               g_main_context_unref (priv->main_context);
-               priv->main_context = NULL;
-       }
-
        if (book_client->priv->direct_book) {
                e_data_book_close_sync (book_client->priv->direct_book, NULL, NULL);
                g_object_unref (book_client->priv->direct_book);
@@ -995,10 +1004,6 @@ e_book_client_init (EBookClient *client)
        g_atomic_int_inc (&active_book_clients);
 
        client->priv = E_BOOK_CLIENT_GET_PRIVATE (client);
-
-       /* This is so the D-Bus thread can schedule signal emissions
-        * on the thread-default context for this thread. */
-       client->priv->main_context = g_main_context_ref_thread_default ();
 }
 
 /**
diff --git a/calendar/libecal/e-cal-client.c b/calendar/libecal/e-cal-client.c
index 66e2563..e938b89 100644
--- a/calendar/libecal/e-cal-client.c
+++ b/calendar/libecal/e-cal-client.c
@@ -54,7 +54,6 @@ typedef struct _ConnectClosure ConnectClosure;
 typedef struct _RunInThreadClosure RunInThreadClosure;
 
 struct _ECalClientPrivate {
-       GMainContext *main_context;
        EDBusCalendar *dbus_proxy;
        guint name_watcher_id;
 
@@ -574,29 +573,34 @@ cal_client_emit_timezone_added_idle_cb (gpointer user_data)
 static void
 cal_client_dbus_proxy_error_cb (EDBusCalendar *dbus_proxy,
                                 const gchar *error_message,
-                                ECalClient *cal_client)
+                                EClient *client)
 {
        GSource *idle_source;
+       GMainContext *main_context;
        SignalClosure *signal_closure;
 
        signal_closure = g_slice_new0 (SignalClosure);
-       signal_closure->client = g_object_ref (cal_client);
+       signal_closure->client = g_object_ref (client);
        signal_closure->error_message = g_strdup (error_message);
 
+       main_context = e_client_ref_main_context (client);
+
        idle_source = g_idle_source_new ();
        g_source_set_callback (
                idle_source,
                cal_client_emit_backend_error_idle_cb,
                signal_closure,
                (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, cal_client->priv->main_context);
+       g_source_attach (idle_source, main_context);
        g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void
 cal_client_dbus_proxy_notify_cb (EDBusCalendar *dbus_proxy,
                                  GParamSpec *pspec,
-                                 ECalClient *cal_client)
+                                 EClient *client)
 {
        const gchar *backend_prop_name = NULL;
 
@@ -623,7 +627,7 @@ cal_client_dbus_proxy_notify_cb (EDBusCalendar *dbus_proxy,
                        csv = g_strjoinv (",", strv);
                        g_strfreev (strv);
                }
-               e_client_set_capabilities (E_CLIENT (cal_client), csv);
+               e_client_set_capabilities (client, csv);
                g_free (csv);
        }
 
@@ -637,7 +641,7 @@ cal_client_dbus_proxy_notify_cb (EDBusCalendar *dbus_proxy,
                backend_prop_name = CLIENT_BACKEND_PROPERTY_ONLINE;
 
                online = e_dbus_calendar_get_online (dbus_proxy);
-               e_client_set_online (E_CLIENT (cal_client), online);
+               e_client_set_online (client, online);
        }
 
        if (g_str_equal (pspec->name, "revision")) {
@@ -650,60 +654,73 @@ cal_client_dbus_proxy_notify_cb (EDBusCalendar *dbus_proxy,
                backend_prop_name = CLIENT_BACKEND_PROPERTY_READONLY;
 
                writable = e_dbus_calendar_get_writable (dbus_proxy);
-               e_client_set_readonly (E_CLIENT (cal_client), !writable);
+               e_client_set_readonly (client, !writable);
        }
 
        if (backend_prop_name != NULL) {
                GSource *idle_source;
+               GMainContext *main_context;
                SignalClosure *signal_closure;
 
                signal_closure = g_slice_new0 (SignalClosure);
-               signal_closure->client = g_object_ref (cal_client);
+               signal_closure->client = g_object_ref (client);
                signal_closure->property_name = g_strdup (backend_prop_name);
 
+               main_context = e_client_ref_main_context (client);
+
                idle_source = g_idle_source_new ();
                g_source_set_callback (
                        idle_source,
                        cal_client_emit_backend_property_changed_idle_cb,
                        signal_closure,
                        (GDestroyNotify) signal_closure_free);
-               g_source_attach (idle_source, cal_client->priv->main_context);
+               g_source_attach (idle_source, main_context);
                g_source_unref (idle_source);
+
+               g_main_context_unref (main_context);
        }
 }
 
 static void
 cal_client_dbus_proxy_free_busy_data_cb (EDBusCalendar *dbus_proxy,
                                          gchar **free_busy_data,
-                                         ECalClient *cal_client)
+                                         EClient *client)
 {
        GSource *idle_source;
+       GMainContext *main_context;
        SignalClosure *signal_closure;
 
        signal_closure = g_slice_new0 (SignalClosure);
-       signal_closure->client = g_object_ref (cal_client);
+       signal_closure->client = g_object_ref (client);
        signal_closure->free_busy_data = g_strdupv (free_busy_data);
 
+       main_context = e_client_ref_main_context (client);
+
        idle_source = g_idle_source_new ();
        g_source_set_callback (
                idle_source,
                cal_client_emit_free_busy_data_idle_cb,
                signal_closure,
                (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, cal_client->priv->main_context);
+       g_source_attach (idle_source, main_context);
        g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void
 cal_client_name_vanished_cb (GDBusConnection *connection,
                              const gchar *name,
-                             ECalClient *cal_client)
+                             EClient *client)
 {
        GSource *idle_source;
+       GMainContext *main_context;
        SignalClosure *signal_closure;
 
        signal_closure = g_slice_new0 (SignalClosure);
-       signal_closure->client = g_object_ref (cal_client);
+       signal_closure->client = g_object_ref (client);
+
+       main_context = e_client_ref_main_context (client);
 
        idle_source = g_idle_source_new ();
        g_source_set_callback (
@@ -711,8 +728,10 @@ cal_client_name_vanished_cb (GDBusConnection *connection,
                cal_client_emit_backend_died_idle_cb,
                signal_closure,
                (GDestroyNotify) signal_closure_free);
-       g_source_attach (idle_source, cal_client->priv->main_context);
+       g_source_attach (idle_source, main_context);
        g_source_unref (idle_source);
+
+       g_main_context_unref (main_context);
 }
 
 static void
@@ -824,11 +843,6 @@ cal_client_dispose (GObject *object)
                priv->dbus_proxy = NULL;
        }
 
-       if (priv->main_context != NULL) {
-               g_main_context_unref (priv->main_context);
-               priv->main_context = NULL;
-       }
-
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_cal_client_parent_class)->dispose (object);
 }
@@ -1195,6 +1209,7 @@ cal_client_add_cached_timezone (ETimezoneCache *cache,
         * been returned through e_timezone_cache_get_timezone(). */
        if (!g_hash_table_contains (priv->zone_cache, tzid)) {
                GSource *idle_source;
+               GMainContext *main_context;
                SignalClosure *signal_closure;
 
                icalcomponent *icalcomp;
@@ -1216,14 +1231,18 @@ cal_client_add_cached_timezone (ETimezoneCache *cache,
                signal_closure->client = g_object_ref (cache);
                signal_closure->cached_zone = cached_zone;
 
+               main_context = e_client_ref_main_context (E_CLIENT (cache));
+
                idle_source = g_idle_source_new ();
                g_source_set_callback (
                        idle_source,
                        cal_client_emit_timezone_added_idle_cb,
                        signal_closure,
                        (GDestroyNotify) signal_closure_free);
-               g_source_attach (idle_source, priv->main_context);
+               g_source_attach (idle_source, main_context);
                g_source_unref (idle_source);
+
+               g_main_context_unref (main_context);
        }
 
        g_mutex_unlock (&priv->zone_cache_lock);
@@ -1421,10 +1440,6 @@ e_cal_client_init (ECalClient *client)
        client->priv->default_zone = icaltimezone_get_utc_timezone ();
        g_mutex_init (&client->priv->zone_cache_lock);
        client->priv->zone_cache = zone_cache;
-
-       /* This is so the D-Bus thread can schedule signal emissions
-        * on the thread-default context for this thread. */
-       client->priv->main_context = g_main_context_ref_thread_default ();
 }
 
 /**
diff --git a/docs/reference/libedataserver/libedataserver-sections.txt 
b/docs/reference/libedataserver/libedataserver-sections.txt
index 71a8415..9b663e2 100644
--- a/docs/reference/libedataserver/libedataserver-sections.txt
+++ b/docs/reference/libedataserver/libedataserver-sections.txt
@@ -49,6 +49,7 @@ CLIENT_BACKEND_PROPERTY_REVISION
 EClient
 e_client_get_source
 e_client_get_capabilities
+e_client_ref_main_context
 e_client_check_capability
 e_client_check_refresh_supported
 e_client_is_readonly
diff --git a/libedataserver/e-client.c b/libedataserver/e-client.c
index e0b8712..53d1b28 100644
--- a/libedataserver/e-client.c
+++ b/libedataserver/e-client.c
@@ -54,6 +54,7 @@ struct _EClientPrivate {
        gboolean online;
        gboolean readonly;
        GSList *capabilities;
+       GMainContext *main_context;
 };
 
 struct _AsyncContext {
@@ -66,6 +67,7 @@ struct _AsyncContext {
 enum {
        PROP_0,
        PROP_CAPABILITIES,
+       PROP_MAIN_CONTEXT,
        PROP_ONLINE,
        PROP_OPENED,
        PROP_READONLY,
@@ -246,6 +248,13 @@ client_get_property (GObject *object,
                                E_CLIENT (object)));
                        return;
 
+               case PROP_MAIN_CONTEXT:
+                       g_value_take_boxed (
+                               value,
+                               e_client_ref_main_context (
+                               E_CLIENT (object)));
+                       return;
+
                case PROP_ONLINE:
                        g_value_set_boolean (
                                value,
@@ -285,6 +294,11 @@ client_dispose (GObject *object)
 
        priv = E_CLIENT_GET_PRIVATE (object);
 
+       if (priv->main_context != NULL) {
+               g_main_context_unref (priv->main_context);
+               priv->main_context = NULL;
+       }
+
        g_clear_object (&priv->source);
 
        /* Chain up to parent's dispose() method. */
@@ -777,6 +791,18 @@ e_client_class_init (EClientClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_MAIN_CONTEXT,
+               g_param_spec_boxed (
+                       "main-context",
+                       "Main Context",
+                       "The main loop context on "
+                       "which to attach event sources",
+                       G_TYPE_MAIN_CONTEXT,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
                PROP_ONLINE,
                g_param_spec_boolean (
                        "online",
@@ -871,6 +897,7 @@ e_client_init (EClient *client)
        client->priv = E_CLIENT_GET_PRIVATE (client);
 
        client->priv->readonly = TRUE;
+       client->priv->main_context = g_main_context_ref_thread_default ();
 
        g_rec_mutex_init (&client->priv->prop_mutex);
 }
@@ -935,6 +962,28 @@ e_client_get_capabilities (EClient *client)
 }
 
 /**
+ * e_client_ref_main_context:
+ * @client: an #EClient
+ *
+ * Returns the #GMainContext on which event sources for @client are to
+ * be attached.
+ *
+ * The returned #GMainContext is referenced for thread-safety and must be
+ * unreferenced with g_main_context_unref() when finished with it.
+ *
+ * Returns: (transfer full): a #GMainContext
+ *
+ * Since: 3.8
+ **/
+GMainContext *
+e_client_ref_main_context (EClient *client)
+{
+       g_return_val_if_fail (E_IS_CLIENT (client), NULL);
+
+       return g_main_context_ref (client->priv->main_context);
+}
+
+/**
  * e_client_check_capability:
  * @client: an #EClient
  * @capability: a capability
diff --git a/libedataserver/e-client.h b/libedataserver/e-client.h
index 5319d9d..69638b4 100644
--- a/libedataserver/e-client.h
+++ b/libedataserver/e-client.h
@@ -284,6 +284,7 @@ GType               e_client_get_type               (void) G_GNUC_CONST;
 
 ESource *      e_client_get_source             (EClient *client);
 const GSList * e_client_get_capabilities       (EClient *client);
+GMainContext * e_client_ref_main_context       (EClient *client);
 gboolean       e_client_check_capability       (EClient *client,
                                                 const gchar *capability);
 gboolean       e_client_check_refresh_supported


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