[telepathy-glib/master] account{,-manager}: refactor _become_ready

Jonny Lamb jonny.lamb at collabora.co.uk
Sat Sep 26 04:14:21 PDT 2009


This is so we don't access anything belonging to the source object
after unreffing the async result, as that could hold the last ref on
the source object.

Signed-off-by: Jonny Lamb <jonny.lamb at collabora.co.uk>
---
 telepathy-glib/account-manager.c |   22 +++++++++++++++++-----
 telepathy-glib/account.c         |   22 +++++++++++++++++-----
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/telepathy-glib/account-manager.c b/telepathy-glib/account-manager.c
index ac7228a..a462f85 100644
--- a/telepathy-glib/account-manager.c
+++ b/telepathy-glib/account-manager.c
@@ -239,20 +239,32 @@ _tp_account_manager_become_ready (TpAccountManager *self,
   if (!_tp_account_manager_feature_in_array (feature, priv->actual_features))
     g_array_append_val (priv->actual_features, feature);
 
-  for (l = priv->callbacks; l != NULL; l = l->next)
+  /* First, find which callbacks are satisfied and add those items
+   * from the remove list. */
+  l = priv->callbacks;
+  while (l != NULL)
     {
+      GList *c = l;
       TpAccountManagerFeatureCallback *cb = l->data;
 
+      l = l->next;
+
       if (_tp_account_manager_check_features (self, cb->features))
         {
-          remove = g_list_prepend (remove, l);
-          g_simple_async_result_complete (cb->result);
-          g_object_unref (cb->result);
+          priv->callbacks = g_list_remove_link (priv->callbacks, c);
+          remove = g_list_concat (remove, c);
         }
     }
 
+  /* Next, complete these callbacks */
   for (l = remove; l != NULL; l = l->next)
-    priv->callbacks = g_list_delete_link (priv->callbacks, l->data);
+    {
+      TpAccountManagerFeatureCallback *cb = l->data;
+
+      g_simple_async_result_complete (cb->result);
+      g_object_unref (cb->result);
+      g_slice_free (TpAccountManagerFeatureCallback, cb);
+    }
 
   g_list_free (remove);
 }
diff --git a/telepathy-glib/account.c b/telepathy-glib/account.c
index 6ebf361..099b17a 100644
--- a/telepathy-glib/account.c
+++ b/telepathy-glib/account.c
@@ -295,20 +295,32 @@ _tp_account_become_ready (TpAccount *self,
   if (!_tp_account_feature_in_array (feature, priv->actual_features))
     g_array_append_val (priv->actual_features, feature);
 
-  for (l = priv->callbacks; l != NULL; l = l->next)
+  /* First, find which callbacks are satisfied and add those items
+   * from the remove list. */
+  l = priv->callbacks;
+  while (l != NULL)
     {
+      GList *c = l;
       TpAccountFeatureCallback *cb = l->data;
 
+      l = l->next;
+
       if (_tp_account_check_features (self, cb->features))
         {
-          remove = g_list_prepend (remove, l);
-          g_simple_async_result_complete (cb->result);
-          g_object_unref (cb->result);
+          priv->callbacks = g_list_remove_link (priv->callbacks, c);
+          remove = g_list_concat (remove, c);
         }
     }
 
+  /* Next, complete these callbacks */
   for (l = remove; l != NULL; l = l->next)
-    priv->callbacks = g_list_delete_link (priv->callbacks, l->data);
+    {
+      TpAccountFeatureCallback *cb = l->data;
+
+      g_simple_async_result_complete (cb->result);
+      g_object_unref (cb->result);
+      g_slice_free (TpAccountFeatureCallback, cb);
+    }
 
   g_list_free (remove);
 }
-- 
1.5.6.5




More information about the telepathy-commits mailing list