[evolution-data-server] Create only one EDataBook per EBookBackend.



commit dd7a8bf666fb89cc5a3b262834a2b9f5ab37e4bc
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Mar 20 11:34:29 2013 -0400

    Create only one EDataBook per EBookBackend.
    
    I've never understood why we create multiple EDataBook instances per
    EBookBackend.  All it's doing is exporting an AddressBook interface on
    the session bus and handling incoming method invocations by forwarding
    them to the EBookBackend.
    
    The GDBusMethodInvocation identifies the client, so we don't need to
    export a separate AddressBook 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_book_backend_ref_data_book()
        e_book_backend_set_data_book()
    
    Deprecated functions:
    
        e_book_backend_add_client()
        e_book_backend_remove_client()

 addressbook/libedata-book/e-book-backend.c         |  144 +++++++++++---------
 addressbook/libedata-book/e-book-backend.h         |   12 +-
 addressbook/libedata-book/e-data-book-factory.c    |   39 ++++--
 addressbook/libedata-book/e-data-book.c            |    3 -
 .../libedata-book/libedata-book-sections.txt       |    6 +-
 5 files changed, 116 insertions(+), 88 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index a578924..cc22aa7 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -22,9 +22,7 @@
 
 struct _EBookBackendPrivate {
        ESourceRegistry *registry;
-
-       GMutex clients_mutex;
-       GList *clients;
+       EDataBook *data_book;
 
        gboolean opened, removed;
        gboolean writable;
@@ -218,10 +216,8 @@ book_backend_dispose (GObject *object)
 
        priv = E_BOOK_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_book);
 
        if (priv->views != NULL) {
                g_list_free (priv->views);
@@ -239,9 +235,6 @@ book_backend_finalize (GObject *object)
 
        priv = E_BOOK_BACKEND_GET_PRIVATE (object);
 
-       g_list_free (priv->clients);
-
-       g_mutex_clear (&priv->clients_mutex);
        g_mutex_clear (&priv->views_mutex);
 
        g_free (priv->cache_dir);
@@ -374,9 +367,6 @@ e_book_backend_init (EBookBackend *backend)
 {
        backend->priv = E_BOOK_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);
 }
@@ -429,6 +419,61 @@ e_book_backend_set_cache_dir (EBookBackend *backend,
 }
 
 /**
+ * e_book_backend_ref_data_book:
+ * @backend: an #EBookBackend
+ *
+ * Returns the #EDataBook for @backend.  The #EDataBook is essentially
+ * the glue between incoming D-Bus requests and @backend's native API.
+ *
+ * An #EDataBook should be set only once after @backend is first created.
+ * If an #EDataBook has not yet been set, the function returns %NULL.
+ *
+ * The returned #EDataBook is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: an #EDataBook, or %NULL
+ *
+ * Since: 3.10
+ **/
+EDataBook *
+e_book_backend_ref_data_book (EBookBackend *backend)
+{
+       EDataBook *data_book = NULL;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), NULL);
+
+       if (backend->priv->data_book != NULL)
+               data_book = g_object_ref (backend->priv->data_book);
+
+       return data_book;
+}
+
+/**
+ * e_book_backend_set_data_book:
+ * @backend: an #EBookBackend
+ * @data_book: an #EDataBook
+ *
+ * Sets the #EDataBook for @backend.  The #EDataBook is essentially the
+ * glue between incoming D-Bus requests and @backend's native API.
+ *
+ * An #EDataBook should be set only once after @backend is first created.
+ *
+ * Since: 3.10
+ **/
+void
+e_book_backend_set_data_book (EBookBackend *backend,
+                              EDataBook *data_book)
+{
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (data_book));
+
+       /* This should be set only once.  Warn if not. */
+       g_warn_if_fail (backend->priv->data_book == NULL);
+
+       backend->priv->data_book = g_object_ref (data_book);
+}
+
+/**
  * e_book_backend_get_registry:
  * @backend: an #EBookBackend
  *
@@ -552,15 +597,9 @@ e_book_backend_open (EBookBackend *backend,
        g_return_if_fail (E_IS_BOOK_BACKEND (backend));
        g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       g_mutex_lock (&backend->priv->clients_mutex);
-
        if (e_book_backend_is_opened (backend)) {
-               g_mutex_unlock (&backend->priv->clients_mutex);
-
                e_data_book_respond_open (book, opid, NULL);
        } else {
-               g_mutex_unlock (&backend->priv->clients_mutex);
-
                g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->open != NULL);
 
                (* E_BOOK_BACKEND_GET_CLASS (backend)->open) (backend, book, opid, cancellable, 
only_if_exists);
@@ -881,18 +920,13 @@ e_book_backend_remove_view (EBookBackend *backend,
  * Adds a client to an addressbook backend.
  *
  * Returns: TRUE on success, FALSE on failure to add the client.
+ *
+ * Deprecated: 3.10: This function no longer does anything.
  */
 gboolean
 e_book_backend_add_client (EBookBackend *backend,
                            EDataBook *book)
 {
-       g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), FALSE);
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-
-       g_mutex_lock (&backend->priv->clients_mutex);
-       backend->priv->clients = g_list_prepend (backend->priv->clients, book);
-       g_mutex_unlock (&backend->priv->clients_mutex);
-
        return TRUE;
 }
 
@@ -902,24 +936,13 @@ e_book_backend_add_client (EBookBackend *backend,
  * @book: an #EDataBook to remove
  *
  * Removes @book from the list of @backend's clients.
+ *
+ * Deprecated: 3.10: This function no longer does anything.
  **/
 void
 e_book_backend_remove_client (EBookBackend *backend,
                               EDataBook *book)
 {
-       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
-       g_return_if_fail (E_IS_DATA_BOOK (book));
-
-       /* 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, book);
-
-       g_mutex_unlock (&backend->priv->clients_mutex);
-
-       g_object_unref (backend);
 }
 
 /**
@@ -1322,17 +1345,17 @@ void
 e_book_backend_notify_error (EBookBackend *backend,
                              const gchar *message)
 {
-       EBookBackendPrivate *priv;
-       GList *clients;
+       EDataBook *data_book;
 
-       priv = backend->priv;
-
-       g_mutex_lock (&priv->clients_mutex);
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+       g_return_if_fail (message != NULL);
 
-       for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
-               e_data_book_report_error (E_DATA_BOOK (clients->data), message);
+       data_book = e_book_backend_ref_data_book (backend);
 
-       g_mutex_unlock (&priv->clients_mutex);
+       if (data_book != NULL) {
+               e_data_book_report_error (data_book, message);
+               g_object_unref (data_book);
+       }
 }
 
 /**
@@ -1403,16 +1426,11 @@ void
 e_book_backend_notify_opened (EBookBackend *backend,
                               GError *error)
 {
-       EBookBackendPrivate *priv;
-
-       priv = backend->priv;
-       g_mutex_lock (&priv->clients_mutex);
-
-       priv->opened = error == NULL;
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
 
-       g_mutex_unlock (&priv->clients_mutex);
+       backend->priv->opened = (error == NULL);
 
-       if (error)
+       if (error != NULL)
                g_error_free (error);
 }
 
@@ -1431,21 +1449,19 @@ e_book_backend_notify_property_changed (EBookBackend *backend,
                                         const gchar *prop_name,
                                         const gchar *prop_value)
 {
-       EBookBackendPrivate *priv;
-       GList *clients;
+       EDataBook *data_book;
 
        g_return_if_fail (E_IS_BOOK_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);
-
-       for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
-               e_data_book_report_backend_property_changed (E_DATA_BOOK (clients->data), prop_name, 
prop_value);
+       data_book = e_book_backend_ref_data_book (backend);
 
-       g_mutex_unlock (&priv->clients_mutex);
+       if (data_book != NULL) {
+               e_data_book_report_backend_property_changed (
+                       data_book, prop_name, prop_value);
+               g_object_unref (data_book);
+       }
 }
 
 /**
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index fe38f3c..505df28 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -213,17 +213,15 @@ GType             e_book_backend_get_type         (void) G_GNUC_CONST;
 const gchar *  e_book_backend_get_cache_dir    (EBookBackend *backend);
 void           e_book_backend_set_cache_dir    (EBookBackend *backend,
                                                 const gchar *cache_dir);
+EDataBook *    e_book_backend_ref_data_book    (EBookBackend *backend);
+void           e_book_backend_set_data_book    (EBookBackend *backend,
+                                                EDataBook *data_book);
 ESourceRegistry *
                e_book_backend_get_registry     (EBookBackend *backend);
 gboolean       e_book_backend_get_writable     (EBookBackend *backend);
 void           e_book_backend_set_writable     (EBookBackend *backend,
                                                 gboolean writable);
 
-gboolean       e_book_backend_add_client       (EBookBackend *backend,
-                                                EDataBook *book);
-void           e_book_backend_remove_client    (EBookBackend *backend,
-                                                EDataBook *book);
-
 gboolean       e_book_backend_is_opened        (EBookBackend *backend);
 gboolean       e_book_backend_is_readonly      (EBookBackend *backend);
 gboolean       e_book_backend_is_removed       (EBookBackend *backend);
@@ -343,6 +341,10 @@ void               e_book_backend_set_is_removed   (EBookBackend *backend,
  **/
 #define BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS   "supported-auth-methods"
 
+gboolean       e_book_backend_add_client       (EBookBackend *backend,
+                                                EDataBook *book);
+void           e_book_backend_remove_client    (EBookBackend *backend,
+                                                EDataBook *book);
 gboolean       e_book_backend_is_opening       (EBookBackend *backend);
 void           e_book_backend_set_backend_property
                                                (EBookBackend *backend,
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index 1a3bff2..a9bb5da 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -317,26 +317,37 @@ data_book_factory_open (EDataBookFactory *factory,
        if (backend == NULL)
                return NULL;
 
-       object_path = construct_book_factory_path ();
+       /* If the backend already has an EDataBook installed, return its
+        * object path.  Otherwise we need to install a new EDataBook. */
 
-       data_book = e_data_book_new (
-               E_BOOK_BACKEND (backend),
-               connection, object_path, error);
+       data_book = e_book_backend_ref_data_book (E_BOOK_BACKEND (backend));
 
        if (data_book != NULL) {
-               e_book_backend_add_client (E_BOOK_BACKEND (backend), data_book);
+               object_path = g_strdup (
+                       e_data_book_get_object_path (data_book));
+       } else {
+               object_path = construct_book_factory_path ();
 
-               data_book_factory_watched_names_add (
-                       factory, connection, sender);
+               data_book = e_data_book_new (
+                       E_BOOK_BACKEND (backend),
+                       connection, object_path, error);
 
-               g_signal_connect_object (
-                       backend, "closed",
-                       G_CALLBACK (data_book_factory_closed_cb),
-                       factory, 0);
+               if (data_book != NULL) {
+                       e_book_backend_set_data_book (
+                               E_BOOK_BACKEND (backend), data_book);
 
-       } else {
-               g_free (object_path);
-               object_path = NULL;
+                       data_book_factory_watched_names_add (
+                               factory, connection, sender);
+
+                       g_signal_connect_object (
+                               backend, "closed",
+                               G_CALLBACK (data_book_factory_closed_cb),
+                               factory, 0);
+
+               } else {
+                       g_free (object_path);
+                       object_path = NULL;
+               }
        }
 
        if (data_book != NULL) {
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 3e7ce25..5175d6b 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -731,9 +731,6 @@ operation_thread (gpointer data,
                break;
 
        case OP_CLOSE:
-               /* close just cancels all pending ops and frees data book */
-               e_book_backend_remove_client (backend, op->book);
-
                if (op->sender != NULL)
                        cancel_operations_for_sender (op->book, op->sender);
 
diff --git a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt 
b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
index e1e5944..eb9ce3a 100644
--- a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
+++ b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
@@ -11,11 +11,11 @@ BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS
 BOOK_BACKEND_PROPERTY_REVISION
 e_book_backend_get_cache_dir
 e_book_backend_set_cache_dir
+e_book_backend_ref_data_book
+e_book_backend_set_data_book
 e_book_backend_get_registry
 e_book_backend_get_writable
 e_book_backend_set_writable
-e_book_backend_add_client
-e_book_backend_remove_client
 e_book_backend_is_opened
 e_book_backend_is_readonly
 e_book_backend_is_removed
@@ -46,6 +46,8 @@ e_book_backend_configure_direct
 CLIENT_BACKEND_PROPERTY_OPENED
 CLIENT_BACKEND_PROPERTY_OPENING
 BOOK_BACKEND_PROPERTY_SUPPORTED_AUTH_METHODS
+e_book_backend_add_client
+e_book_backend_remove_client
 e_book_backend_is_opening
 e_book_backend_set_backend_property
 e_book_backend_foreach_view


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