[telepathy-gabble/master] tube-stream: fire ConnectionClosed with Cancelled error if transport is disconnected

Guillaume Desmottes guillaume.desmottes at collabora.co.uk
Wed May 20 10:01:54 PDT 2009


---
 src/tube-stream.c |   48 ++++++++++++++++++++++++++++++++++++------------
 1 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/tube-stream.c b/src/tube-stream.c
index bba106a..97aedc6 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -68,6 +68,8 @@
   "org.freedesktop.Telepathy.Error.ConnectionLost"
 #define GABBLE_ERROR_STR_CONNECTION_REFUSED \
   "org.freedesktop.Telepathy.Error.ConnectionRefused"
+#define GABBLE_ERROR_STR_CANCELLED \
+  "org.freedesktop.Telepathy.Error.Cancelled"
 
 static void channel_iface_init (gpointer, gpointer);
 static void tube_iface_init (gpointer g_iface, gpointer iface_data);
@@ -258,20 +260,13 @@ transport_handler (GibberTransport *transport,
       (const gchar *) data->data);
 }
 
-static void
-transport_disconnected_cb (GibberTransport *transport,
-                           GabbleTubeStream *self)
+static gboolean
+connection_closed_has_been_fired (GabbleTubeStream *self,
+    GibberTransport *transport)
 {
   GabbleTubeStreamPrivate *priv = GABBLE_TUBE_STREAM_GET_PRIVATE (self);
-  GabbleBytestreamIface *bytestream;
-
-  bytestream = g_hash_table_lookup (priv->transport_to_bytestream, transport);
-  if (bytestream == NULL)
-    return;
-
-  DEBUG ("transport disconnected. close the extra bytestream");
 
-  gabble_bytestream_iface_close (bytestream, NULL);
+  return g_hash_table_lookup (priv->transport_to_id, transport) == NULL;
 }
 
 static void
@@ -286,11 +281,33 @@ fire_connection_closed (GabbleTubeStream *self,
         transport));
   g_assert (connection_id != 0);
 
+  /* remove the ID so we are sure we won't fire ConnectionClosed twice for the
+   * same connection. */
+  g_hash_table_remove (priv->transport_to_id, transport);
+
   gabble_svc_channel_type_stream_tube_emit_connection_closed (self,
       connection_id, error);
 }
 
 static void
+transport_disconnected_cb (GibberTransport *transport,
+                           GabbleTubeStream *self)
+{
+  GabbleTubeStreamPrivate *priv = GABBLE_TUBE_STREAM_GET_PRIVATE (self);
+  GabbleBytestreamIface *bytestream;
+
+  fire_connection_closed (self, transport, GABBLE_ERROR_STR_CANCELLED);
+
+  bytestream = g_hash_table_lookup (priv->transport_to_bytestream, transport);
+  if (bytestream == NULL)
+    return;
+
+  DEBUG ("transport disconnected. close the extra bytestream");
+
+  gabble_bytestream_iface_close (bytestream, NULL);
+}
+
+static void
 remove_transport (GabbleTubeStream *self,
                   GabbleBytestreamIface *bytestream,
                   GibberTransport *transport)
@@ -308,7 +325,14 @@ remove_transport (GabbleTubeStream *self,
 
   gibber_transport_disconnect (transport);
 
-  fire_connection_closed (self, transport, GABBLE_ERROR_STR_CONNECTION_LOST);
+  /* if ConnectionClosed has not been fired yet at this point that means we
+   * are removing the transport because of an external event so we use the
+   * ConnectionLost error. */
+  if (!connection_closed_has_been_fired (self, transport))
+    {
+      fire_connection_closed (self, transport,
+          GABBLE_ERROR_STR_CONNECTION_LOST);
+    }
 
   /* the transport may not be in transport_to_bytestream if the bytestream was
    * not fully open */
-- 
1.5.6.5




More information about the telepathy-commits mailing list