[evolution-data-server] Create only one EDataCal per ECalBackend.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Create only one EDataCal per ECalBackend.
- Date: Wed, 20 Mar 2013 22:54:40 +0000 (UTC)
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]