[next] telepathy-gabble: all TpChannelManager implementations: remove before emitting ChannelClosed

Simon McVittie smcv at kemper.freedesktop.org
Wed May 7 02:18:41 PDT 2014


Module: telepathy-gabble
Branch: next
Commit: ab83c3b6dd634c06d030d7cb3d7761bb4b7f81ea
URL:    http://cgit.freedesktop.org/telepathy/telepathy-gabble/commit/?id=ab83c3b6dd634c06d030d7cb3d7761bb4b7f81ea

Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date:   Tue Apr 22 12:49:01 2014 +0100

all TpChannelManager implementations: remove before emitting ChannelClosed

When TpBaseConnection updates its idea of the Channels property
in response to our channel-closed signal, we don't want it to list the
just-closed channel in foreach_channel().

Similarly, make sure we survive foreach_channel() being called during
disconnection, even if we have destroyed the data structure storing
our channels.

The IM and MUC managers are (as usual) more subtle than the rest
because of their "respawning" behaviour: if we're respawning channels,
we need to emit channel-closed before new-channel, otherwise the D-Bus
signals will be in the wrong order (but if we're not, we need to emit
channel-closed last).

The FT manager didn't actually emit channel-closed at all, so fix that.

---

 src/auth-manager.c          |    6 +++---
 src/ft-manager.c            |    3 +++
 src/im-factory.c            |   18 ++++++++++++------
 src/media-factory.c         |    6 +++---
 src/muc-factory.c           |   33 +++++++++++++++++++--------------
 src/private-tubes-factory.c |    9 ++++++---
 src/roomlist-manager.c      |    9 ++++++---
 src/search-manager.c        |    5 ++++-
 8 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/src/auth-manager.c b/src/auth-manager.c
index 7f3055a..8d13e0f 100644
--- a/src/auth-manager.c
+++ b/src/auth-manager.c
@@ -114,9 +114,6 @@ auth_channel_closed_cb (GabbleServerSaslChannel *channel,
 {
   SavedError tmp = { NULL, NULL, 0, NULL };
 
-  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
-      TP_BASE_CHANNEL (channel));
-
   g_assert (self->priv->channel == channel);
 
   /* this is our last chance to find out why it failed */
@@ -133,6 +130,9 @@ auth_channel_closed_cb (GabbleServerSaslChannel *channel,
   tp_clear_pointer (&self->priv->server, g_free);
   tp_clear_pointer (&self->priv->session_id, g_free);
   tp_clear_pointer (&self->priv->username, g_free);
+
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
+      TP_BASE_CHANNEL (channel));
 }
 
 static void
diff --git a/src/ft-manager.c b/src/ft-manager.c
index bb8a2f7..53804c3 100644
--- a/src/ft-manager.c
+++ b/src/ft-manager.c
@@ -282,6 +282,9 @@ file_channel_closed_cb (GabbleFileTransferChannel *chan,
       g_free (id);
       g_free (path);
     }
+
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
+      TP_BASE_CHANNEL (chan));
 }
 
 #ifdef ENABLE_JINGLE_FILE_TRANSFER
diff --git a/src/im-factory.c b/src/im-factory.c
index 4b0f52d..2327df7 100644
--- a/src/im-factory.c
+++ b/src/im-factory.c
@@ -322,12 +322,6 @@ im_channel_closed_cb (GabbleIMChannel *chan, gpointer user_data)
 
   DEBUG ("%p, channel %p", self, chan);
 
-  if (tp_base_channel_is_registered (base))
-    {
-      tp_channel_manager_emit_channel_closed_for_object (
-          TP_CHANNEL_MANAGER (self), base);
-    }
-
   if (priv->channels != NULL)
     {
       if (tp_base_channel_is_destroyed (base))
@@ -335,11 +329,20 @@ im_channel_closed_cb (GabbleIMChannel *chan, gpointer user_data)
           DEBUG ("removing channel with handle %u", contact_handle);
           g_hash_table_remove (priv->channels,
               GUINT_TO_POINTER (contact_handle));
+
+          if (tp_base_channel_is_registered (base))
+            tp_channel_manager_emit_channel_closed_for_object (
+                TP_CHANNEL_MANAGER (self), base);
         }
       else if (tp_base_channel_is_respawning (base))
         {
           DEBUG ("reopening channel with handle %u due to pending messages",
               contact_handle);
+
+          if (tp_base_channel_is_registered (base))
+            tp_channel_manager_emit_channel_closed_for_object (
+                TP_CHANNEL_MANAGER (self), base);
+
           tp_channel_manager_emit_new_channel (TP_CHANNEL_MANAGER (self),
               base, NULL);
         }
@@ -672,6 +675,9 @@ gabble_im_factory_foreach_channel (TpChannelManager *manager,
   GabbleImFactory *self = GABBLE_IM_FACTORY (manager);
   struct _ForeachData data;
 
+  if (self->priv->channels == NULL)
+    return;
+
   data.user_data = user_data;
   data.func = func;
 
diff --git a/src/media-factory.c b/src/media-factory.c
index 7d6a432..f5eaf9d 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -208,14 +208,14 @@ call_channel_closed_cb (GabbleCallChannel *chan, gpointer user_data)
   GabbleMediaFactory *fac = GABBLE_MEDIA_FACTORY (user_data);
   GabbleMediaFactoryPrivate *priv = fac->priv;
 
-  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (fac),
-      TP_BASE_CHANNEL (chan));
-
   DEBUG ("removing media channel %p with ref count %d",
       chan, G_OBJECT (chan)->ref_count);
 
   priv->call_channels = g_list_remove (priv->call_channels, chan);
   g_object_unref (chan);
+
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (fac),
+      TP_BASE_CHANNEL (chan));
 }
 
 static void
diff --git a/src/muc-factory.c b/src/muc-factory.c
index 48cb1b8..a1d2fb9 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -255,17 +255,13 @@ muc_channel_closed_cb (GabbleMucChannel *chan, gpointer user_data)
   /* channel is actually reappearing, announce it */
   if (tp_base_channel_is_respawning (base))
     {
+      tp_channel_manager_emit_channel_closed_for_object (
+          TP_CHANNEL_MANAGER (fac), base);
       tp_channel_manager_emit_new_channel (TP_CHANNEL_MANAGER (fac),
           base, NULL);
       return;
     }
 
-  if (tp_base_channel_is_registered (base))
-    {
-      tp_channel_manager_emit_channel_closed_for_object (
-          TP_CHANNEL_MANAGER (fac), base);
-    }
-
   if (tp_base_channel_is_destroyed (base)
       && priv->text_channels != NULL)
     {
@@ -275,6 +271,12 @@ muc_channel_closed_cb (GabbleMucChannel *chan, gpointer user_data)
 
       g_hash_table_remove (priv->text_channels, GUINT_TO_POINTER (room_handle));
     }
+
+  if (tp_base_channel_is_registered (base))
+    {
+      tp_channel_manager_emit_channel_closed_for_object (
+          TP_CHANNEL_MANAGER (fac), base);
+    }
 }
 
 static void
@@ -392,21 +394,21 @@ muc_sub_channel_closed_cb (TpSvcChannel *chan,
   GabbleMucFactory *fac = GABBLE_MUC_FACTORY (user_data);
   GabbleMucChannel *muc;
 
-  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (fac),
-      TP_BASE_CHANNEL (chan));
-
   /* GabbleTubeDBus, GabbleTubeStream, and GabbleMucCallChannel all
    * have "muc" properties. */
   g_object_get (chan,
       "muc", &muc,
       NULL);
 
-  if (muc == NULL)
-    return;
+  if (muc != NULL)
+    {
+      if (gabble_muc_channel_can_be_closed (muc)
+          && gabble_muc_channel_get_autoclose (muc))
+        tp_base_channel_close (TP_BASE_CHANNEL (muc));
+    }
 
-  if (gabble_muc_channel_can_be_closed (muc)
-      && gabble_muc_channel_get_autoclose (muc))
-    tp_base_channel_close (TP_BASE_CHANNEL (muc));
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (fac),
+      TP_BASE_CHANNEL (chan));
 }
 
 #ifdef ENABLE_VOIP
@@ -1005,6 +1007,9 @@ gabble_muc_factory_foreach_channel (TpChannelManager *manager,
   GHashTableIter iter;
   gpointer value;
 
+  if (priv->text_channels == NULL)
+    return;
+
   g_hash_table_iter_init (&iter, priv->text_channels);
   while (g_hash_table_iter_next (&iter, NULL, &value))
     {
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 82a33f9..8f936bb 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -653,6 +653,9 @@ gabble_private_tubes_factory_foreach_channel (TpChannelManager *manager,
   GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (manager);
   struct _ForeachData data;
 
+  if (self->priv->tubes == NULL)
+    return;
+
   data.user_data = user_data;
   data.foreach = foreach;
 
@@ -972,11 +975,11 @@ channel_closed_cb (GabbleTubeIface *tube,
       "id", &id,
       NULL);
 
-  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
-      TP_BASE_CHANNEL (tube));
-
   if (self->priv->tubes != NULL)
     g_hash_table_remove (self->priv->tubes, GUINT_TO_POINTER (id));
+
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
+      TP_BASE_CHANNEL (tube));
 }
 
 static guint64
diff --git a/src/roomlist-manager.c b/src/roomlist-manager.c
index 202672b..848257c 100644
--- a/src/roomlist-manager.c
+++ b/src/roomlist-manager.c
@@ -246,6 +246,9 @@ gabble_roomlist_manager_foreach_channel (TpChannelManager *manager,
   GabbleRoomlistManager *self = GABBLE_ROOMLIST_MANAGER (manager);
   guint i;
 
+  if (self->priv->channels == NULL)
+    return;
+
   for (i = 0; i < self->priv->channels->len; i++)
     {
       TpBaseChannel *channel = TP_BASE_CHANNEL (
@@ -297,14 +300,14 @@ roomlist_channel_closed_cb (GabbleRoomlistChannel *channel,
 {
   GabbleRoomlistManager *self = GABBLE_ROOMLIST_MANAGER (user_data);
 
-  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
-      TP_BASE_CHANNEL (channel));
-
   if (self->priv->channels != NULL)
     {
       g_ptr_array_remove (self->priv->channels, channel);
       g_object_unref (channel);
     }
+
+  tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
+      TP_BASE_CHANNEL (channel));
 }
 
 
diff --git a/src/search-manager.c b/src/search-manager.c
index 1016ff5..e761445 100644
--- a/src/search-manager.c
+++ b/src/search-manager.c
@@ -303,6 +303,9 @@ gabble_search_manager_foreach_channel (TpChannelManager *manager,
   GHashTableIter iter;
   gpointer chan;
 
+  if (self->priv->channels == NULL)
+    return;
+
   g_hash_table_iter_init (&iter, self->priv->channels);
   while (g_hash_table_iter_next (&iter, &chan, NULL))
     {
@@ -354,9 +357,9 @@ static void
 search_channel_closed_cb (GabbleSearchChannel *chan,
                           GabbleSearchManager *self)
 {
+  remove_search_channel (self, chan);
   tp_channel_manager_emit_channel_closed_for_object (TP_CHANNEL_MANAGER (self),
       (TpBaseChannel *) chan);
-  remove_search_channel (self, chan);
 }
 
 typedef struct {



More information about the telepathy-commits mailing list