[next] telepathy-glib: TpChannel: simplify the contacts queue now that we have only upgrades

Xavier Claessens xclaesse at kemper.freedesktop.org
Fri May 18 09:03:48 PDT 2012


Module: telepathy-glib
Branch: next
Commit: 1976f829e02d3c9a663dac47b26e11de8c979080
URL:    http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=1976f829e02d3c9a663dac47b26e11de8c979080

Author: Xavier Claessens <xavier.claessens at collabora.co.uk>
Date:   Fri May 18 18:02:07 2012 +0200

TpChannel: simplify the contacts queue now that we have only upgrades

---

 telepathy-glib/channel-group.c |  159 +++++++++++----------------------------
 1 files changed, 45 insertions(+), 114 deletions(-)

diff --git a/telepathy-glib/channel-group.c b/telepathy-glib/channel-group.c
index ed56901..e885841 100644
--- a/telepathy-glib/channel-group.c
+++ b/telepathy-glib/channel-group.c
@@ -187,82 +187,45 @@ dup_owners_table (TpChannel *self,
   return target;
 }
 
-struct _ContactsQueueItem
-{
-  TpChannel *channel;
-  GPtrArray *contacts;
-  GPtrArray *ids;
-  GArray *handles;
-};
-
-static void
-contacts_queue_item_free (ContactsQueueItem *item)
-{
-  g_clear_object (&item->channel);
-  tp_clear_pointer (&item->contacts, g_ptr_array_unref);
-  tp_clear_pointer (&item->ids, g_ptr_array_unref);
-  tp_clear_pointer (&item->handles, g_array_unref);
-  g_slice_free (ContactsQueueItem, item);
-}
-
 static void process_contacts_queue (TpChannel *self);
 
 static void
-contacts_queue_head_ready (TpChannel *self,
-    const GError *error)
-{
-  GSimpleAsyncResult *result = self->priv->current_contacts_queue_result;
-
-  if (error != NULL)
-    {
-      DEBUG ("Error preparing channel contacts queue item: %s", error->message);
-      g_simple_async_result_set_from_error (result, error);
-    }
-  g_simple_async_result_complete (result);
-
-  self->priv->current_contacts_queue_result = NULL;
-  process_contacts_queue (self);
-
-  g_object_unref (result);
-}
-
-static void
-contacts_queue_item_upgraded_cb (GObject *object,
+contacts_queue_upgraded_cb (GObject *object,
     GAsyncResult *result,
     gpointer user_data)
 {
-  TpConnection *connection = (TpConnection *) object;
-  ContactsQueueItem *item = user_data;
+  TpChannel *self = user_data;
+  TpClientFactory *factory = (TpClientFactory *) object;
+  GSimpleAsyncResult *my_result = self->priv->current_contacts_queue_result;
   GError *error = NULL;
 
-  tp_connection_upgrade_contacts_finish (connection, result, NULL, &error);
-  contacts_queue_head_ready (item->channel, error);
-  g_clear_error (&error);
-}
+  if (!tp_client_factory_upgrade_contacts_finish (factory, result, NULL,
+          &error))
+    {
+      DEBUG ("Error preparing channel contacts: %s", error->message);
+      g_simple_async_result_take_error (my_result, error);
+    }
 
-static gboolean
-contacts_queue_item_idle_cb (gpointer user_data)
-{
-  TpChannel *self = user_data;
+  g_simple_async_result_complete (my_result);
 
-  contacts_queue_head_ready (self, NULL);
+  self->priv->current_contacts_queue_result = NULL;
+  process_contacts_queue (self);
 
-  return FALSE;
+  g_object_unref (my_result);
 }
 
 static void
 process_contacts_queue (TpChannel *self)
 {
   GSimpleAsyncResult *result;
-  ContactsQueueItem *item;
-  GArray *features;
+  GPtrArray *contacts;
   const GError *error = NULL;
 
   if (self->priv->current_contacts_queue_result != NULL)
     return;
 
-  /* self can't die while there are queued items because item->result keeps a
-   * ref to it. But it could have been invalidated. */
+  /* self can't die while there are queued results because GSimpleAsyncResult
+   * keep a ref to it. But it could have been invalidated. */
   error = tp_proxy_get_invalidated (self);
   if (error != NULL)
     {
@@ -278,72 +241,57 @@ process_contacts_queue (TpChannel *self)
       return;
     }
 
+next:
   result = g_queue_pop_head (self->priv->contacts_queue);
-
   if (result == NULL)
     return;
 
-  self->priv->current_contacts_queue_result = result;
-  item = g_simple_async_result_get_op_res_gpointer (result);
-
-  features = tp_client_factory_dup_contact_features (
-      tp_proxy_get_factory (self->priv->connection), self->priv->connection);
-
-  if (item->contacts != NULL && item->contacts->len > 0)
-    {
-      g_assert (item->ids == NULL);
-      g_assert (item->handles == NULL);
-
-      tp_connection_upgrade_contacts_async (self->priv->connection,
-          item->contacts->len, (TpContact **) item->contacts->pdata,
-          (const GQuark *) features->data,
-          contacts_queue_item_upgraded_cb,
-          item);
-    }
-  else
+  contacts = g_simple_async_result_get_op_res_gpointer (result);
+  if (contacts == NULL || contacts->len == 0)
     {
       /* It can happen there is no contact to prepare, and can still be useful
        * in order to not reorder some events.
        * We have to use an idle though, to guarantee callback is never called
        * without reentering mainloop first. */
-      g_idle_add (contacts_queue_item_idle_cb, self);
+      g_simple_async_result_complete_in_idle (result);
+      g_object_unref (result);
+      goto next;
     }
 
-  g_array_unref (features);
+  self->priv->current_contacts_queue_result = result;
+  tp_client_factory_upgrade_contacts_async (
+      tp_proxy_get_factory (self->priv->connection),
+      self->priv->connection,
+      contacts->len, (TpContact **) contacts->pdata,
+      contacts_queue_upgraded_cb,
+      self);
 }
 
-static void
-contacts_queue_item (TpChannel *self,
+void
+_tp_channel_contacts_queue_prepare_async (TpChannel *self,
     GPtrArray *contacts,
-    GPtrArray *ids,
-    GArray *handles,
     GAsyncReadyCallback callback,
     gpointer user_data)
 {
-  ContactsQueueItem *item = g_slice_new (ContactsQueueItem);
   GSimpleAsyncResult *result;
 
-  item->channel = g_object_ref (self);
-  item->contacts = contacts != NULL ? g_ptr_array_ref (contacts) : NULL;
-  item->ids = ids != NULL ? g_ptr_array_ref (ids) : NULL;
-  item->handles = handles != NULL ? g_array_ref (handles) : NULL;
-  result = g_simple_async_result_new ((GObject *) self,
-      callback, user_data, contacts_queue_item);
+  result = g_simple_async_result_new ((GObject *) self, callback, user_data,
+      _tp_channel_contacts_queue_prepare_async);
 
-  g_simple_async_result_set_op_res_gpointer (result, item,
-      (GDestroyNotify) contacts_queue_item_free);
+  if (contacts != NULL)
+    {
+      g_simple_async_result_set_op_res_gpointer (result,
+          g_ptr_array_ref (contacts), (GDestroyNotify) g_ptr_array_unref);
+    }
 
   g_queue_push_tail (self->priv->contacts_queue, result);
   process_contacts_queue (self);
 }
 
-void
-_tp_channel_contacts_queue_prepare_async (TpChannel *self,
-    GPtrArray *contacts,
-    GAsyncReadyCallback callback,
-    gpointer user_data)
+static gpointer
+safe_g_ptr_array_ref (GPtrArray *array)
 {
-  contacts_queue_item (self, contacts, NULL, NULL, callback, user_data);
+  return (array != NULL) ? g_ptr_array_ref (array) : NULL;
 }
 
 gboolean
@@ -352,26 +300,9 @@ _tp_channel_contacts_queue_prepare_finish (TpChannel *self,
     GPtrArray **contacts,
     GError **error)
 {
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-  ContactsQueueItem *item;
-
-  item = g_simple_async_result_get_op_res_gpointer (simple);
-
-  if (contacts != NULL)
-    {
-      if (item->contacts != NULL)
-        *contacts = g_ptr_array_ref (item->contacts);
-      else
-        *contacts = g_ptr_array_new ();
-    }
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    return FALSE;
-
-  g_return_val_if_fail (g_simple_async_result_is_valid (result,
-      G_OBJECT (self), contacts_queue_item), FALSE);
-
-  return TRUE;
+  _tp_implement_finish_copy_pointer (self,
+      _tp_channel_contacts_queue_prepare_async,
+      safe_g_ptr_array_ref, contacts);
 }
 
 static void



More information about the telepathy-commits mailing list