[evolution-data-server] Create only one EDataCal per ECalBackend.



commit ec6f79b03a34c49d0d01c3ddbde87fc8a69da194
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Mar 20 17:15:53 2013 -0400

    Create only one EDataCal per ECalBackend.
    
    I've never understood why we create multiple EDataCal instances per
    ECalBackend.  All it's doing is exporting a Calendar interface on the
    session bus and handling incoming method invocations by forwarding them
    to the ECalBackend.
    
    The GDBusMethodInvocation identifies the client, so we don't need to
    export a separate Calendar interface per client.  This seems to be a
    relic of the Bonobo-era design.
    
    Fixing this redundancy is a prerequisite to running backends in child
    processes, which is one of my goals for 3.10.
    
    New functions:
    
        e_cal_backend_ref_data_cal()
        e_cal_backend_set_data_cal()
    
    Deprecated functions:
    
       e_cal_backend_add_client()
       e_cal_backend_remove_client()

 calendar/libedata-cal/e-cal-backend.c              |  183 +++++++++-----------
 calendar/libedata-cal/e-cal-backend.h              |   12 +-
 calendar/libedata-cal/e-data-cal-factory.c         |   39 +++--
 calendar/libedata-cal/e-data-cal.c                 |    3 -
 .../libedata-cal/libedata-cal-sections.txt         |    6 +-
 5 files changed, 117 insertions(+), 126 deletions(-)
---
diff --git a/calendar/libedata-cal/e-cal-backend.c b/calendar/libedata-cal/e-cal-backend.c
index e807703..5c9496a 100644
--- a/calendar/libedata-cal/e-cal-backend.c
+++ b/calendar/libedata-cal/e-cal-backend.c
@@ -41,6 +41,8 @@ typedef struct _SignalClosure SignalClosure;
 struct _ECalBackendPrivate {
        ESourceRegistry *registry;
 
+       EDataCal *data_cal;
+
        /* The kind of components for this backend */
        icalcomponent_kind kind;
 
@@ -49,10 +51,6 @@ struct _ECalBackendPrivate {
 
        gchar *cache_dir;
 
-       /* List of Cal objects */
-       GMutex clients_mutex;
-       GList *clients;
-
        GMutex views_mutex;
        GList *views;
 
@@ -85,10 +83,6 @@ enum {
 static guint signals[LAST_SIGNAL];
 
 /* Forward Declarations */
-static void    e_cal_backend_remove_client_private
-                                       (ECalBackend *backend,
-                                        EDataCal *cal,
-                                        gboolean weak_unref);
 static void    e_cal_backend_timezone_cache_init
                                        (ETimezoneCacheInterface *interface);
 
@@ -339,10 +333,8 @@ cal_backend_dispose (GObject *object)
 
        priv = E_CAL_BACKEND_GET_PRIVATE (object);
 
-       if (priv->registry != NULL) {
-               g_object_unref (priv->registry);
-               priv->registry = NULL;
-       }
+       g_clear_object (&priv->registry);
+       g_clear_object (&priv->data_cal);
 
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_cal_backend_parent_class)->dispose (object);
@@ -355,12 +347,6 @@ cal_backend_finalize (GObject *object)
 
        priv = E_CAL_BACKEND_GET_PRIVATE (object);
 
-       g_assert (priv->clients == NULL);
-
-       /* should be NULL, anyway */
-       g_list_free (priv->clients);
-       g_mutex_clear (&priv->clients_mutex);
-
        g_list_free (priv->views);
        g_mutex_clear (&priv->views_mutex);
 
@@ -663,9 +649,6 @@ e_cal_backend_init (ECalBackend *backend)
 
        backend->priv = E_CAL_BACKEND_GET_PRIVATE (backend);
 
-       backend->priv->clients = NULL;
-       g_mutex_init (&backend->priv->clients_mutex);
-
        backend->priv->views = NULL;
        g_mutex_init (&backend->priv->views_mutex);
 
@@ -690,6 +673,61 @@ e_cal_backend_get_kind (ECalBackend *backend)
 }
 
 /**
+ * e_cal_backend_ref_data_cal:
+ * @backend: an #ECalBackend
+ *
+ * Returns the #EDataCal for @backend.  The #EDataCal is essentially
+ * the glue between incoming D-Bus requests and @backend's native API.
+ *
+ * An #EDataCal should be set only once after @backend is first created.
+ * If an #EDataCal has not yet been set, the function returns %NULL.
+ *
+ * The returned #EDataCal is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: an #EDataCal, or %NULL
+ *
+ * Since: 3.10
+ **/
+EDataCal *
+e_cal_backend_ref_data_cal (ECalBackend *backend)
+{
+       EDataCal *data_cal = NULL;
+
+       g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL);
+
+       if (backend->priv->data_cal != NULL)
+               data_cal = g_object_ref (backend->priv->data_cal);
+
+       return data_cal;
+}
+
+/**
+ * e_cal_backend_set_data_book:
+ * @backend: an #ECalBackend
+ * @data_cal: an #EDataCal
+ *
+ * Sets the #EDataCal for @backend.  The #EDataCal is essentially the
+ * glue between incoming D-Bus requests and @backend's native API.
+ *
+ * An #EDataCal should be set only once after @backend is first created.
+ *
+ * Since: 3.10
+ **/
+void
+e_cal_backend_set_data_cal (ECalBackend *backend,
+                            EDataCal *data_cal)
+{
+       g_return_if_fail (E_IS_CAL_BACKEND (backend));
+       g_return_if_fail (E_IS_DATA_CAL (data_cal));
+
+       /* This should be set only once.  Warn if not. */
+       g_warn_if_fail (backend->priv->data_cal == NULL);
+
+       backend->priv->data_cal = g_object_ref (data_cal);
+}
+
+/**
  * e_cal_backend_get_registry:
  * @backend: an #ECalBackend
  *
@@ -982,15 +1020,6 @@ e_cal_backend_set_backend_property (ECalBackend *backend,
        /* Do nothing. */
 }
 
-static void
-cal_destroy_cb (gpointer data,
-                GObject *where_cal_was)
-{
-       e_cal_backend_remove_client_private (
-               E_CAL_BACKEND (data),
-               (EDataCal *) where_cal_was, FALSE);
-}
-
 /**
  * e_cal_backend_add_client:
  * @backend: an #ECalBackend
@@ -998,48 +1027,13 @@ cal_destroy_cb (gpointer data,
  *
  * Adds a new client to the given backend. For any event, the backend will
  * notify all clients added via this function.
+ *
+ * Deprecated: 3.10: This function no longer does anything.
  */
 void
 e_cal_backend_add_client (ECalBackend *backend,
                           EDataCal *cal)
 {
-       ECalBackendPrivate *priv;
-
-       g_return_if_fail (backend != NULL);
-       g_return_if_fail (E_IS_CAL_BACKEND (backend));
-       g_return_if_fail (cal != NULL);
-       g_return_if_fail (E_IS_DATA_CAL (cal));
-
-       priv = backend->priv;
-
-       g_object_weak_ref (G_OBJECT (cal), cal_destroy_cb, backend);
-
-       g_mutex_lock (&priv->clients_mutex);
-       priv->clients = g_list_append (priv->clients, cal);
-       g_mutex_unlock (&priv->clients_mutex);
-}
-
-static void
-e_cal_backend_remove_client_private (ECalBackend *backend,
-                                     EDataCal *cal,
-                                     gboolean weak_unref)
-{
-       g_return_if_fail (E_IS_CAL_BACKEND (backend));
-       g_return_if_fail (E_IS_DATA_CAL (cal));
-
-       if (weak_unref)
-               g_object_weak_unref (G_OBJECT (cal), cal_destroy_cb, backend);
-
-       /* Make sure the backend stays alive while holding the mutex. */
-       g_object_ref (backend);
-
-       /* Disconnect */
-       g_mutex_lock (&backend->priv->clients_mutex);
-       backend->priv->clients = g_list_remove (backend->priv->clients, cal);
-
-       g_mutex_unlock (&backend->priv->clients_mutex);
-
-       g_object_unref (backend);
 }
 
 /**
@@ -1048,12 +1042,13 @@ e_cal_backend_remove_client_private (ECalBackend *backend,
  * @cal: an #EDataCal
  *
  * Removes a client from the list of connected clients to the given backend.
+ *
+ * Deprecated: 3.10: This function no longer does anything.
  */
 void
 e_cal_backend_remove_client (ECalBackend *backend,
                              EDataCal *cal)
 {
-       e_cal_backend_remove_client_private (backend, cal, TRUE);
 }
 
 /**
@@ -1262,15 +1257,9 @@ e_cal_backend_open (ECalBackend *backend,
        g_return_if_fail (E_IS_CAL_BACKEND (backend));
        g_return_if_fail (E_CAL_BACKEND_GET_CLASS (backend)->open != NULL);
 
-       g_mutex_lock (&backend->priv->clients_mutex);
-
        if (e_cal_backend_is_opened (backend)) {
-               g_mutex_unlock (&backend->priv->clients_mutex);
-
                e_data_cal_respond_open (cal, opid, NULL);
        } else {
-               g_mutex_unlock (&backend->priv->clients_mutex);
-
                (* E_CAL_BACKEND_GET_CLASS (backend)->open) (backend, cal, opid, cancellable, only_if_exists);
        }
 }
@@ -1915,20 +1904,17 @@ void
 e_cal_backend_notify_error (ECalBackend *backend,
                             const gchar *message)
 {
-       ECalBackendPrivate *priv = backend->priv;
-       GList *l;
-
-       if (priv->notification_proxy) {
-               e_cal_backend_notify_error (priv->notification_proxy, message);
-               return;
-       }
+       EDataCal *data_cal;
 
-       g_mutex_lock (&priv->clients_mutex);
+       g_return_if_fail (E_IS_CAL_BACKEND (backend));
+       g_return_if_fail (message != NULL);
 
-       for (l = priv->clients; l; l = l->next)
-               e_data_cal_report_error (l->data, message);
+       data_cal = e_cal_backend_ref_data_cal (backend);
 
-       g_mutex_unlock (&priv->clients_mutex);
+       if (data_cal != NULL) {
+               e_data_cal_report_error (data_cal, message);
+               g_object_unref (data_cal);
+       }
 }
 
 /**
@@ -1998,16 +1984,11 @@ void
 e_cal_backend_notify_opened (ECalBackend *backend,
                              GError *error)
 {
-       ECalBackendPrivate *priv;
-
-       priv = backend->priv;
-       g_mutex_lock (&priv->clients_mutex);
-
-       priv->opened = error == NULL;
+       g_return_if_fail (E_IS_CAL_BACKEND (backend));
 
-       g_mutex_unlock (&priv->clients_mutex);
+       backend->priv->opened = (error == NULL);
 
-       if (error)
+       if (error != NULL)
                g_error_free (error);
 }
 
@@ -2026,21 +2007,19 @@ e_cal_backend_notify_property_changed (ECalBackend *backend,
                                        const gchar *prop_name,
                                        const gchar *prop_value)
 {
-       ECalBackendPrivate *priv;
-       GList *clients;
+       EDataCal *data_cal;
 
        g_return_if_fail (E_IS_CAL_BACKEND (backend));
        g_return_if_fail (prop_name != NULL);
-       g_return_if_fail (*prop_name != '\0');
        g_return_if_fail (prop_value != NULL);
 
-       priv = backend->priv;
-       g_mutex_lock (&priv->clients_mutex);
+       data_cal = e_cal_backend_ref_data_cal (backend);
 
-       for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
-               e_data_cal_report_backend_property_changed (E_DATA_CAL (clients->data), prop_name, 
prop_value);
-
-       g_mutex_unlock (&priv->clients_mutex);
+       if (data_cal != NULL) {
+               e_data_cal_report_backend_property_changed (
+                       data_cal, prop_name, prop_value);
+               g_object_unref (data_cal);
+       }
 }
 
 /**
diff --git a/calendar/libedata-cal/e-cal-backend.h b/calendar/libedata-cal/e-cal-backend.h
index fba96d7..49264f3 100644
--- a/calendar/libedata-cal/e-cal-backend.h
+++ b/calendar/libedata-cal/e-cal-backend.h
@@ -248,6 +248,9 @@ struct _ECalBackendClass {
 GType          e_cal_backend_get_type          (void) G_GNUC_CONST;
 icalcomponent_kind
                e_cal_backend_get_kind          (ECalBackend *backend);
+EDataCal *     e_cal_backend_ref_data_cal      (ECalBackend *backend);
+void           e_cal_backend_set_data_cal      (ECalBackend *backend,
+                                                EDataCal *data_cal);
 ESourceRegistry *
                e_cal_backend_get_registry      (ECalBackend *backend);
 gboolean       e_cal_backend_get_writable      (ECalBackend *backend);
@@ -266,11 +269,6 @@ gchar *            e_cal_backend_create_cache_filename
                                                 const gchar *filename,
                                                 gint fileindex);
 
-void           e_cal_backend_add_client        (ECalBackend *backend,
-                                                EDataCal *cal);
-void           e_cal_backend_remove_client     (ECalBackend *backend,
-                                                EDataCal *cal);
-
 void           e_cal_backend_add_view          (ECalBackend *backend,
                                                 EDataCalView *view);
 void           e_cal_backend_remove_view       (ECalBackend *backend,
@@ -423,6 +421,10 @@ void               e_cal_backend_set_is_removed    (ECalBackend *backend,
  **/
 #define CLIENT_BACKEND_PROPERTY_OPENING                        "opening"
 
+void           e_cal_backend_add_client        (ECalBackend *backend,
+                                                EDataCal *cal);
+void           e_cal_backend_remove_client     (ECalBackend *backend,
+                                                EDataCal *cal);
 gboolean       e_cal_backend_is_opening        (ECalBackend *backend);
 void           e_cal_backend_set_backend_property
                                                (ECalBackend *backend,
diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c
index 08d64f6..53d3246 100644
--- a/calendar/libedata-cal/e-data-cal-factory.c
+++ b/calendar/libedata-cal/e-data-cal-factory.c
@@ -323,26 +323,37 @@ data_cal_factory_open (EDataCalFactory *factory,
        if (backend == NULL)
                return NULL;
 
-       object_path = construct_cal_factory_path ();
+       /* If the backend already has an EDataCal installed, return its
+        * object path.  Otherwise we need to install a new EDataCal. */
 
-       data_cal = e_data_cal_new (
-               E_CAL_BACKEND (backend),
-               connection, object_path, error);
+       data_cal = e_cal_backend_ref_data_cal (E_CAL_BACKEND (backend));
 
        if (data_cal != NULL) {
-               e_cal_backend_add_client (E_CAL_BACKEND (backend), data_cal);
+               object_path = g_strdup (
+                       e_data_cal_get_object_path (data_cal));
+       } else {
+               object_path = construct_cal_factory_path ();
 
-               data_cal_factory_watched_names_add (
-                       factory, connection, sender);
+               data_cal = e_data_cal_new (
+                       E_CAL_BACKEND (backend),
+                       connection, object_path, error);
 
-               g_signal_connect_object (
-                       backend, "closed",
-                       G_CALLBACK (data_cal_factory_closed_cb),
-                       factory, 0);
+               if (data_cal != NULL) {
+                       e_cal_backend_set_data_cal (
+                               E_CAL_BACKEND (backend), data_cal);
 
-       } else {
-               g_free (object_path);
-               object_path = NULL;
+                       data_cal_factory_watched_names_add (
+                               factory, connection, sender);
+
+                       g_signal_connect_object (
+                               backend, "closed",
+                               G_CALLBACK (data_cal_factory_closed_cb),
+                               factory, 0);
+
+               } else {
+                       g_free (object_path);
+                       object_path = NULL;
+               }
        }
 
        if (data_cal != NULL) {
diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c
index 72ca994..b62872e 100644
--- a/calendar/libedata-cal/e-data-cal.c
+++ b/calendar/libedata-cal/e-data-cal.c
@@ -687,9 +687,6 @@ operation_thread (gpointer data,
                break;
 
        case OP_CLOSE:
-               /* close just cancels all pending ops and frees data cal */
-               e_cal_backend_remove_client (backend, op->cal);
-
                if (op->sender != NULL)
                        cancel_operations_for_sender (op->cal, op->sender);
 
diff --git a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt 
b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
index 02c4a32..e67a3ad 100644
--- a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
+++ b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
@@ -11,6 +11,8 @@ CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS
 CAL_BACKEND_PROPERTY_DEFAULT_OBJECT
 CAL_BACKEND_PROPERTY_REVISION
 e_cal_backend_get_kind
+e_cal_backend_ref_data_cal
+e_cal_backend_set_data_cal
 e_cal_backend_get_registry
 e_cal_backend_get_writable
 e_cal_backend_set_writable
@@ -20,8 +22,6 @@ e_cal_backend_is_removed
 e_cal_backend_get_cache_dir
 e_cal_backend_set_cache_dir
 e_cal_backend_create_cache_filename
-e_cal_backend_add_client
-e_cal_backend_remove_client
 e_cal_backend_add_view
 e_cal_backend_remove_view
 e_cal_backend_list_views
@@ -53,6 +53,8 @@ e_cal_backend_set_is_removed
 <SUBSECTION Deprecated>
 CLIENT_BACKEND_PROPERTY_OPENED
 CLIENT_BACKEND_PROPERTY_OPENING
+e_cal_backend_add_client
+e_cal_backend_remove_client
 e_cal_backend_is_opening
 e_cal_backend_set_backend_property
 e_cal_backend_foreach_view


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