From 36d0cef62397b9cde55f18c21d089b9510af6997 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 7 Oct 2012 18:23:56 -0400 Subject: [PATCH] Remove e_data_cal_register_gdbus_object(). The first thing we do after creating a new EDataCal is export its D-Bus interface. This was a separate and failable operation. If the exporting fails, the EDataCal is useless. Perfect use case for GInitable. Now we pass the GDBusConnection and object path directly to e_data_cal_new(), and if the exporting fails the function sets a GError and returns NULL. This also introduces a couple accessor functions: e_data_cal_get_connection() e_data_cal_get_object_path() --- calendar/libedata-cal/e-data-cal-factory.c | 52 ++--- calendar/libedata-cal/e-data-cal.c | 219 ++++++++++++++++++--- calendar/libedata-cal/e-data-cal.h | 12 +- .../libedata-cal/libedata-cal-sections.txt | 3 +- 4 files changed, 229 insertions(+), 57 deletions(-) diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c index 9899c31..bbe6b45 100644 --- a/calendar/libedata-cal/e-data-cal-factory.c +++ b/calendar/libedata-cal/e-data-cal-factory.c @@ -203,7 +203,7 @@ impl_CalFactory_get_cal (EGdbusCalFactory *object, GDBusConnection *connection; ESourceRegistry *registry; ESource *source; - gchar *path = NULL; + gchar *object_path; const gchar *sender; GList *list; GError *error = NULL; @@ -262,39 +262,45 @@ impl_CalFactory_get_cal (EGdbusCalFactory *object, g_return_val_if_fail (E_IS_BACKEND (backend), FALSE); - g_mutex_lock (priv->calendars_lock); - e_dbus_server_hold (E_DBUS_SERVER (factory)); - path = construct_cal_factory_path (); - calendar = e_data_cal_new (E_CAL_BACKEND (backend)); - g_hash_table_insert (priv->calendars, g_strdup (path), calendar); - e_cal_backend_add_client (E_CAL_BACKEND (backend), calendar); - e_data_cal_register_gdbus_object (calendar, connection, path, &error); - g_object_weak_ref ( - G_OBJECT (calendar), (GWeakNotify) - calendar_freed_cb, factory); + object_path = construct_cal_factory_path (); - g_object_unref (backend); + calendar = e_data_cal_new ( + E_CAL_BACKEND (backend), + connection, object_path, &error); - /* Update the hash of open connections. */ - g_mutex_lock (priv->connections_lock); - list = g_hash_table_lookup (priv->connections, sender); - list = g_list_prepend (list, calendar); - g_hash_table_insert (priv->connections, g_strdup (sender), list); - g_mutex_unlock (priv->connections_lock); + if (calendar != NULL) { + g_mutex_lock (priv->calendars_lock); + g_hash_table_insert ( + priv->calendars, g_strdup (object_path), calendar); + g_mutex_unlock (priv->calendars_lock); - g_mutex_unlock (priv->calendars_lock); + e_cal_backend_add_client (E_CAL_BACKEND (backend), calendar); - g_free (uid); + g_object_weak_ref ( + G_OBJECT (calendar), (GWeakNotify) + calendar_freed_cb, factory); + + /* Update the hash of open connections. */ + g_mutex_lock (priv->connections_lock); + list = g_hash_table_lookup (priv->connections, sender); + list = g_list_prepend (list, calendar); + g_hash_table_insert ( + priv->connections, g_strdup (sender), list); + g_mutex_unlock (priv->connections_lock); + } + + g_object_unref (backend); e_gdbus_cal_factory_complete_get_cal ( - object, invocation, path, error); + object, invocation, object_path, error); - if (error) + if (error != NULL) g_error_free (error); - g_free (path); + g_free (object_path); + g_free (uid); return TRUE; } diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c index 5e6accb..2a2e038 100644 --- a/calendar/libedata-cal/e-data-cal.c +++ b/calendar/libedata-cal/e-data-cal.c @@ -45,9 +45,10 @@ #define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg) struct _EDataCalPrivate { + GDBusConnection *connection; EGdbusCal *gdbus_object; - ECalBackend *backend; + gchar *object_path; GStaticRecMutex pending_ops_lock; GHashTable *pending_ops; /* opid to GCancellable for still running operations */ @@ -55,7 +56,9 @@ struct _EDataCalPrivate { enum { PROP_0, - PROP_BACKEND + PROP_BACKEND, + PROP_CONNECTION, + PROP_OBJECT_PATH }; static EOperationPool *ops_pool = NULL; @@ -149,7 +152,16 @@ typedef struct { } d; } OperationData; -G_DEFINE_TYPE (EDataCal, e_data_cal, G_TYPE_OBJECT); +/* Forward Declarations */ +static void e_data_cal_initable_init (GInitableIface *interface); + +G_DEFINE_TYPE_WITH_CODE ( + EDataCal, + e_data_cal, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE ( + G_TYPE_INITABLE, + e_data_cal_initable_init)) /* Function to get a new EDataCalView path, used by get_view below */ static gchar * @@ -500,27 +512,6 @@ e_data_cal_create_error_fmt (EDataCalCallStatus status, return error; } -/** - * e_data_cal_register_gdbus_object: - * - * Registers GDBus object of this EDataCal. - * - * Since: 2.32 - **/ -guint -e_data_cal_register_gdbus_object (EDataCal *cal, - GDBusConnection *connection, - const gchar *object_path, - GError **error) -{ - g_return_val_if_fail (cal != NULL, 0); - g_return_val_if_fail (E_IS_DATA_CAL (cal), 0); - g_return_val_if_fail (connection != NULL, 0); - g_return_val_if_fail (object_path != NULL, 0); - - return e_gdbus_cal_register_object (cal->priv->gdbus_object, connection, object_path, error); -} - static gboolean impl_Cal_open (EGdbusCal *object, GDBusMethodInvocation *invocation, @@ -1532,6 +1523,26 @@ data_cal_set_backend (EDataCal *cal, } static void +data_cal_set_connection (EDataCal *cal, + GDBusConnection *connection) +{ + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (cal->priv->connection == NULL); + + cal->priv->connection = g_object_ref (connection); +} + +static void +data_cal_set_object_path (EDataCal *cal, + const gchar *object_path) +{ + g_return_if_fail (object_path != NULL); + g_return_if_fail (cal->priv->object_path == NULL); + + cal->priv->object_path = g_strdup (object_path); +} + +static void data_cal_set_property (GObject *object, guint property_id, const GValue *value, @@ -1543,6 +1554,18 @@ data_cal_set_property (GObject *object, E_DATA_CAL (object), g_value_get_object (value)); return; + + case PROP_CONNECTION: + data_cal_set_connection ( + E_DATA_CAL (object), + g_value_get_object (value)); + return; + + case PROP_OBJECT_PATH: + data_cal_set_object_path ( + E_DATA_CAL (object), + g_value_get_string (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -1561,6 +1584,20 @@ data_cal_get_property (GObject *object, e_data_cal_get_backend ( E_DATA_CAL (object))); return; + + case PROP_CONNECTION: + g_value_set_object ( + value, + e_data_cal_get_connection ( + E_DATA_CAL (object))); + return; + + case PROP_OBJECT_PATH: + g_value_set_string ( + value, + e_data_cal_get_object_path ( + E_DATA_CAL (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -1573,7 +1610,12 @@ data_cal_dispose (GObject *object) priv = E_DATA_CAL_GET_PRIVATE (object); - if (priv->backend) { + if (priv->connection != NULL) { + g_object_unref (priv->connection); + priv->connection = NULL; + } + + if (priv->backend != NULL) { g_object_unref (priv->backend); priv->backend = NULL; } @@ -1589,6 +1631,8 @@ data_cal_finalize (GObject *object) priv = E_DATA_CAL_GET_PRIVATE (object); + g_free (priv->object_path); + if (priv->pending_ops) { g_hash_table_destroy (priv->pending_ops); priv->pending_ops = NULL; @@ -1605,6 +1649,22 @@ data_cal_finalize (GObject *object) G_OBJECT_CLASS (e_data_cal_parent_class)->finalize (object); } +static gboolean +data_cal_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + EDataCal *cal; + + cal = E_DATA_CAL (initable); + + return e_gdbus_cal_register_object ( + cal->priv->gdbus_object, + cal->priv->connection, + cal->priv->object_path, + error); +} + static void e_data_cal_class_init (EDataCalClass *class) { @@ -1630,11 +1690,43 @@ e_data_cal_class_init (EDataCalClass *class) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property ( + object_class, + PROP_CONNECTION, + g_param_spec_object ( + "connection", + "Connection", + "The GDBusConnection on which to " + "export the calendar interface", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_OBJECT_PATH, + g_param_spec_string ( + "object-path", + "Object Path", + "The object path at which to " + "export the calendar interface", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + if (!ops_pool) ops_pool = e_operation_pool_new (10, operation_thread, NULL); } static void +e_data_cal_initable_init (GInitableIface *interface) +{ + interface->init = data_cal_initable_init; +} + +static void e_data_cal_init (EDataCal *ecal) { EGdbusCal *gdbus_object; @@ -1709,14 +1801,47 @@ e_data_cal_init (EDataCal *ecal) G_CALLBACK (impl_Cal_close), ecal); } +/** + * e_data_cal_new: + * @backend: an #ECalBackend + * @connection: a #GDBusConnection + * @object_path: object path for the D-Bus interface + * @error: return location for a #GError, or %NULL + * + * Creates a new #EDataCal and exports the Calendar D-Bus interface + * on @connection at @object_path. The #EDataCal handles incoming remote + * method invocations and forwards them to the @backend. If the Calendar + * interface fails to export, the function sets @error and returns %NULL. + * + * Returns: an #EDataCal, or %NULL on error + **/ EDataCal * -e_data_cal_new (ECalBackend *backend) +e_data_cal_new (ECalBackend *backend, + GDBusConnection *connection, + const gchar *object_path, + GError **error) { g_return_val_if_fail (E_IS_CAL_BACKEND (backend), NULL); - - return g_object_new (E_TYPE_DATA_CAL, "backend", backend, NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (object_path != NULL, NULL); + + return g_initable_new ( + E_TYPE_DATA_CAL, NULL, error, + "backend", backend, + "connection", connection, + "object-path", object_path, + NULL); } +/** + * e_data_cal_get_backend: + * @cal: an #EDataCal + * + * Returns the #ECalBackend to which incoming remote method invocations + * are being forwarded. + * + * Returns: the #ECalBackend + **/ ECalBackend * e_data_cal_get_backend (EDataCal *cal) { @@ -1725,3 +1850,41 @@ e_data_cal_get_backend (EDataCal *cal) return cal->priv->backend; } +/** + * e_data_cal_get_connection: + * @cal: an #EDataCal + * + * Returns the #GDBusConnection on which the Calendar D-Bus interface + * is exported. + * + * Returns: the #GDBusConnection + * + * Since: 3.8 + **/ +GDBusConnection * +e_data_cal_get_connection (EDataCal *cal) +{ + g_return_val_if_fail (E_IS_DATA_CAL (cal), NULL); + + return cal->priv->connection; +} + +/** + * e_data_cal_get_object_path: + * @cal: an #EDataCal + * + * Returns the object path at which the Calendar D-Bus interface is + * exported. + * + * Returns: the object path + * + * Since: 3.8 + **/ +const gchar * +e_data_cal_get_object_path (EDataCal *cal) +{ + g_return_val_if_fail (E_IS_DATA_CAL (cal), NULL); + + return cal->priv->object_path; +} + diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h index b8ad92e..c3c54ea 100644 --- a/calendar/libedata-cal/e-data-cal.h +++ b/calendar/libedata-cal/e-data-cal.h @@ -124,14 +124,16 @@ GError * e_data_cal_create_error_fmt (EDataCalCallStatus status, const gchar * e_data_cal_status_to_string (EDataCalCallStatus status); GType e_data_cal_get_type (void) G_GNUC_CONST; -EDataCal * e_data_cal_new (struct _ECalBackend *backend); -struct _ECalBackend * - e_data_cal_get_backend (EDataCal *cal); -guint e_data_cal_register_gdbus_object - (EDataCal *cal, +EDataCal * e_data_cal_new (struct _ECalBackend *backend, GDBusConnection *connection, const gchar *object_path, GError **error); +struct _ECalBackend * + e_data_cal_get_backend (EDataCal *cal); +GDBusConnection * + e_data_cal_get_connection (EDataCal *cal); +const gchar * e_data_cal_get_object_path (EDataCal *cal); + void e_data_cal_respond_open (EDataCal *cal, guint32 opid, GError *error); diff --git a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt index 249d3b2..0c679ab 100644 --- a/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt +++ b/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt @@ -261,7 +261,8 @@ e_return_data_cal_error_if_fail e_return_data_cal_error_val_if_fail e_data_cal_new e_data_cal_get_backend -e_data_cal_register_gdbus_object +e_data_cal_get_connection +e_data_cal_get_object_path e_data_cal_respond_open e_data_cal_respond_refresh e_data_cal_respond_get_backend_property -- 2.7.4