[Pkg-telepathy-commits] [telepathy-glib-1] 53/212: TpConnectionManager: Use GDBusConnection directly to call ListNames
Simon McVittie
smcv at debian.org
Wed May 14 12:08:51 UTC 2014
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian
in repository telepathy-glib-1.
commit b656ea2bc827ba8998d77f0b0c215e170b6b687d
Author: Xavier Claessens <xavier.claessens at collabora.com>
Date: Wed Mar 26 14:40:44 2014 -0400
TpConnectionManager: Use GDBusConnection directly to call ListNames
This rewrites tp_list_connection_managers_async() to simplify the
implementation.
Reviewed-by: Simon McVittie <simon.mcvittie at collabora.co.uk>
---
telepathy-glib/connection-manager.c | 373 ++++++++++++------------------------
1 file changed, 120 insertions(+), 253 deletions(-)
diff --git a/telepathy-glib/connection-manager.c b/telepathy-glib/connection-manager.c
index 0bb6f1b..b01b65a 100644
--- a/telepathy-glib/connection-manager.c
+++ b/telepathy-glib/connection-manager.c
@@ -1211,113 +1211,62 @@ tp_connection_manager_activate (TpConnectionManager *self)
return TRUE;
}
-static gboolean
-steal_into_ptr_array (gpointer key,
- gpointer value,
- gpointer user_data)
+typedef struct
+{
+ TpDBusDaemon *dbus_daemon;
+ /* name -> TpConnectionManager */
+ GHashTable *cms;
+ guint n_operations;
+} ListCMSData;
+
+static ListCMSData *
+list_cms_data_new (TpDBusDaemon *dbus_daemon)
{
- if (value != NULL)
- g_ptr_array_add (user_data, value);
+ ListCMSData *data;
- g_free (key);
+ data = g_slice_new0 (ListCMSData);
+ data->dbus_daemon = g_object_ref (dbus_daemon);
+ data->cms = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
- return TRUE;
+ return data;
}
-typedef void (*TpConnectionManagerListCb) (TpConnectionManager * const *cms,
- gsize n_cms,
- const GError *error,
- gpointer user_data,
- GObject *weak_object);
-
-typedef struct
-{
- GHashTable *table;
- GPtrArray *arr;
- GSimpleAsyncResult *result;
- TpConnectionManagerListCb callback;
- gpointer user_data;
- GDestroyNotify destroy;
- gpointer weak_object;
- TpProxyPendingCall *pending_call;
- size_t base_len;
- gsize refcount;
- gsize cms_to_ready;
- unsigned getting_names:1;
- unsigned had_weak_object:1;
-} _ListContext;
-
static void
-list_context_unref (_ListContext *list_context)
+list_cms_data_free (ListCMSData *data)
{
- guint i;
-
- if (--list_context->refcount > 0)
- return;
-
- if (list_context->weak_object != NULL)
- g_object_remove_weak_pointer (list_context->weak_object,
- &list_context->weak_object);
-
- if (list_context->destroy != NULL)
- list_context->destroy (list_context->user_data);
-
- if (list_context->arr != NULL)
- {
- for (i = 0; i < list_context->arr->len; i++)
- {
- TpConnectionManager *cm = g_ptr_array_index (list_context->arr, i);
-
- if (cm != NULL)
- g_object_unref (cm);
- }
-
- g_ptr_array_unref (list_context->arr);
- }
-
- g_hash_table_unref (list_context->table);
- g_slice_free (_ListContext, list_context);
+ g_object_unref (data->dbus_daemon);
+ g_hash_table_unref (data->cms);
+ g_slice_free (ListCMSData, data);
}
static void
-all_cms_prepared (_ListContext *list_context)
+list_cms_task_maybe_done (GTask *task)
{
- TpConnectionManager **cms;
- guint n_cms = list_context->arr->len;
-
- DEBUG ("We've prepared as many as possible of %u CMs", n_cms);
+ ListCMSData *data = g_task_get_task_data (task);
- g_assert (list_context->callback != NULL);
+ if (data->n_operations == 0 && !g_task_had_error (task))
+ {
+ GList *cms;
- g_ptr_array_add (list_context->arr, NULL);
- cms = (TpConnectionManager **) list_context->arr->pdata;
+ cms = g_hash_table_get_values (data->cms);
+ g_list_foreach (cms, (GFunc) g_object_ref, NULL);
- /* If we never had a weak object anyway, call the callback.
- * If we had a weak object when we started, only call the callback
- * if it hasn't died yet. */
- if (!list_context->had_weak_object || list_context->weak_object != NULL)
- {
- list_context->callback (cms, n_cms, NULL, list_context->user_data,
- list_context->weak_object);
+ g_task_return_pointer (task, cms, (GDestroyNotify) _tp_object_list_free);
}
-
- list_context->callback = NULL;
}
static void
-tp_list_connection_managers_cm_prepared (GObject *source,
+cm_prepared_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- _ListContext *list_context = user_data;
+ TpConnectionManager *cm = (TpConnectionManager *) source;
+ GTask *task = user_data;
+ ListCMSData *data = g_task_get_task_data (task);
GError *error = NULL;
- TpConnectionManager *cm = TP_CONNECTION_MANAGER (source);
- if (tp_proxy_prepare_finish (source, result, &error))
- {
- DEBUG ("%s: prepared", cm->priv->name);
- }
- else
+ if (!tp_proxy_prepare_finish (cm, result, &error))
{
DEBUG ("%s: failed to prepare, continuing: %s #%d: %s", cm->priv->name,
g_quark_to_string (error->domain), error->code, error->message);
@@ -1326,185 +1275,110 @@ tp_list_connection_managers_cm_prepared (GObject *source,
* the CM is ready *if possible* */
}
- list_context->cms_to_ready--;
-
- if (list_context->cms_to_ready == 0)
- {
- all_cms_prepared (list_context);
- }
- else
- {
- DEBUG ("We still need to prepare %" G_GSIZE_FORMAT " CM(s)",
- list_context->cms_to_ready);
- }
+ data->n_operations--;
+ list_cms_task_maybe_done (task);
- list_context_unref (list_context);
+ g_object_unref (task);
}
static void
-tp_list_connection_managers_got_names (TpDBusDaemon *bus_daemon,
- const gchar * const *names,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
+handle_list_names_reply (GTask *task,
+ GVariant *reply)
{
- _ListContext *list_context = user_data;
- const gchar * const *name_iter;
- const gchar *method;
-
- if (list_context->getting_names)
- method = "ListNames";
- else
- method = "ListActivatableNames";
+ ListCMSData *data = g_task_get_task_data (task);
+ const gchar **names;
+ const gchar **iter;
- /* The TpProxy APIs we use guarantee this */
- g_assert (weak_object != NULL || !list_context->had_weak_object);
-
- if (error != NULL)
+ g_variant_get (reply, "(^a&s)", &names);
+ for (iter = names; *iter != NULL; iter++)
{
- DEBUG ("%s failed: %s #%d: %s", method,
- g_quark_to_string (error->domain), error->code, error->message);
- list_context->callback (NULL, 0, error, list_context->user_data,
- weak_object);
- return;
- }
-
- DEBUG ("%s succeeded", method);
-
- for (name_iter = names; name_iter != NULL && *name_iter != NULL; name_iter++)
- {
- const gchar *name;
TpConnectionManager *cm;
+ const gchar *cm_name;
- if (strncmp (TP_CM_BUS_NAME_BASE, *name_iter, list_context->base_len)
- != 0)
+ if (!g_str_has_prefix (*iter, TP_CM_BUS_NAME_BASE) ||
+ g_hash_table_contains (data->cms, *iter))
continue;
- name = *name_iter + list_context->base_len;
- DEBUG (" found CM: %s", name);
-
- if (g_hash_table_lookup (list_context->table, name) == NULL)
- {
- /* just ignore connection managers with bad names */
- cm = tp_connection_manager_new (bus_daemon, name, NULL, NULL);
- if (cm != NULL)
- g_hash_table_insert (list_context->table, g_strdup (name), cm);
- }
- }
-
- if (list_context->getting_names)
- {
- /* now that we have all the CMs, wait for them all to be ready */
- guint i;
-
- list_context->arr = g_ptr_array_sized_new (g_hash_table_size
- (list_context->table));
-
- g_hash_table_foreach_steal (list_context->table, steal_into_ptr_array,
- list_context->arr);
-
- list_context->cms_to_ready = list_context->arr->len;
- list_context->refcount += list_context->cms_to_ready;
-
- DEBUG ("Total of %" G_GSIZE_FORMAT " CMs to be prepared",
- list_context->cms_to_ready);
-
- if (list_context->cms_to_ready == 0)
- {
- all_cms_prepared (list_context);
- return;
- }
+ /* just ignore connection managers with bad names */
+ cm_name = *iter + strlen (TP_CM_BUS_NAME_BASE);
+ cm = tp_connection_manager_new (data->dbus_daemon, cm_name, NULL, NULL);
+ if (cm == NULL)
+ continue;
- for (i = 0; i < list_context->cms_to_ready; i++)
- {
- TpConnectionManager *cm = g_ptr_array_index (list_context->arr, i);
+ g_hash_table_insert (data->cms, g_strdup (*iter), cm);
- DEBUG (" preparing %s", cm->priv->name);
- tp_proxy_prepare_async (cm, NULL,
- tp_list_connection_managers_cm_prepared, list_context);
- }
- }
- else
- {
- DEBUG ("Calling ListNames");
- list_context->getting_names = TRUE;
- list_context->refcount++;
- tp_dbus_daemon_list_names (bus_daemon, 2000,
- tp_list_connection_managers_got_names, list_context,
- (GDestroyNotify) list_context_unref, weak_object);
+ data->n_operations++;
+ tp_proxy_prepare_async (cm, NULL,
+ cm_prepared_cb, g_object_ref (task));
}
+ g_free (names);
+ g_variant_unref (reply);
}
static void
-tp_list_connection_managers (TpDBusDaemon *bus_daemon,
- TpConnectionManagerListCb callback,
- gpointer user_data,
- GDestroyNotify destroy,
- GObject *weak_object)
+list_names_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
- _ListContext *list_context = g_slice_new0 (_ListContext);
-
- list_context->base_len = strlen (TP_CM_BUS_NAME_BASE);
- list_context->callback = callback;
- list_context->user_data = user_data;
- list_context->destroy = destroy;
-
- list_context->getting_names = FALSE;
- list_context->refcount = 1;
- list_context->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- g_object_unref);
- list_context->arr = NULL;
- list_context->cms_to_ready = 0;
+ GDBusConnection *dbus_connection = (GDBusConnection *) source;
+ GTask *task = user_data;
+ ListCMSData *data = g_task_get_task_data (task);
+ GVariant *reply;
+ GError *error = NULL;
- if (weak_object != NULL)
+ reply = g_dbus_connection_call_finish (dbus_connection, result, &error);
+ if (reply == NULL)
{
- list_context->weak_object = weak_object;
- list_context->had_weak_object = TRUE;
- g_object_add_weak_pointer (weak_object, &list_context->weak_object);
+ g_task_return_error (task, error);
+ goto out;
}
- DEBUG ("Calling ListActivatableNames");
- tp_dbus_daemon_list_activatable_names (bus_daemon, 2000,
- tp_list_connection_managers_got_names, list_context,
- (GDestroyNotify) list_context_unref, weak_object);
+ handle_list_names_reply (task, reply);
+
+ data->n_operations--;
+ list_cms_task_maybe_done (task);
+
+out:
+ g_object_unref (task);
}
static void
-list_connection_managers_async_cb (TpConnectionManager * const *cms,
- gsize n_cms,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
+list_activatable_names_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GSimpleAsyncResult *result = user_data;
+ GDBusConnection *dbus_connection = (GDBusConnection *) source;
+ GTask *task = user_data;
+ ListCMSData *data = g_task_get_task_data (task);
+ GVariant *reply;
+ GError *error = NULL;
- if (error != NULL)
+ reply = g_dbus_connection_call_finish (dbus_connection, result, &error);
+ if (reply == NULL)
{
- g_simple_async_result_set_from_error (result, error);
+ g_task_return_error (task, error);
+ goto out;
}
- else
- {
- GList *l = NULL;
- gsize i;
-
- for (i = 0; i < n_cms; i++)
- l = g_list_prepend (l, g_object_ref (cms[i]));
- l = g_list_reverse (l);
+ handle_list_names_reply (task, reply);
- g_simple_async_result_set_op_res_gpointer (result, l,
- (GDestroyNotify) _tp_object_list_free);
- }
+ data->n_operations++;
+ g_dbus_connection_call (dbus_connection,
+ "org.freedesktop.DBus", "/", "org.freedesktop.DBus",
+ "ListNames",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000, NULL,
+ list_names_cb, g_object_ref (task));
- g_simple_async_result_complete_in_idle (result);
-
- /* result is unreffed by GDestroyNotify */
+out:
+ g_object_unref (task);
}
/**
* tp_list_connection_managers_async:
- * @dbus_daemon: (allow-none): a #TpDBusDaemon, or %NULL to use
- * tp_dbus_daemon_dup()
+ * @dbus_daemon: a #TpDBusDaemon
* @callback: a callback to call with a list of CMs
* @user_data: data to pass to @callback
*
@@ -1519,29 +1393,22 @@ tp_list_connection_managers_async (TpDBusDaemon *dbus_daemon,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
- GError *error = NULL;
-
- if (dbus_daemon == NULL)
- dbus_daemon = tp_dbus_daemon_dup (&error);
- else
- g_object_ref (dbus_daemon);
-
- result = g_simple_async_result_new (NULL, callback, user_data,
- tp_list_connection_managers_async);
-
- if (dbus_daemon == NULL)
- {
- g_simple_async_result_take_error (result, error);
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
- }
- else
- {
- tp_list_connection_managers (dbus_daemon,
- list_connection_managers_async_cb, result, g_object_unref, NULL);
- g_object_unref (dbus_daemon);
- }
+ GTask *task;
+ ListCMSData *data;
+
+ task = g_task_new (NULL, NULL, callback, user_data);
+
+ data = list_cms_data_new (dbus_daemon);
+ g_task_set_task_data (task, data, (GDestroyNotify) list_cms_data_free);
+
+ g_dbus_connection_call (tp_proxy_get_dbus_connection (dbus_daemon),
+ "org.freedesktop.DBus", "/", "org.freedesktop.DBus",
+ "ListActivatableNames",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000, NULL,
+ list_activatable_names_cb, task);
}
/**
@@ -1562,9 +1429,9 @@ GList *
tp_list_connection_managers_finish (GAsyncResult *result,
GError **error)
{
- _tp_implement_finish_return_copy_pointer (NULL,
- tp_list_connection_managers_async,
- _tp_object_list_copy);
+ g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
}
/**
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/telepathy-glib-1.git
More information about the Pkg-telepathy-commits
mailing list