[Telepathy-commits] [telepathy-sofiasip/master] Resurrect a text channel if it has pending incoming messages

Mikhail Zabaluev mikhail.zabaluev at nokia.com
Tue Oct 21 05:19:25 PDT 2008


---
 src/sip-text-channel.c |   57 ++++++++++++++++++++++++++++++++---------------
 src/sip-text-channel.h |    3 --
 src/text-factory.c     |   35 +++++++++++++++++-----------
 3 files changed, 60 insertions(+), 35 deletions(-)

diff --git a/src/sip-text-channel.c b/src/sip-text-channel.c
index a20f333..2851e7a 100644
--- a/src/sip-text-channel.c
+++ b/src/sip-text-channel.c
@@ -427,7 +427,10 @@ tpsip_text_channel_dispose(GObject *object)
   priv->dispose_has_run = TRUE;
 
   if (!priv->closed)
-    tpsip_text_channel_close (self);
+    {
+      priv->closed = TRUE;
+      tp_svc_channel_emit_closed (self);
+    }
 
   contact_handles = tp_base_connection_get_handles (
       (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
@@ -566,32 +569,51 @@ tpsip_text_channel_acknowledge_pending_messages(TpSvcChannelTypeText *iface,
 
 
 /**
- * tpsip_text_channel_close_async
+ * tpsip_text_channel_close
  *
  * Implements DBus method Close
  * on interface org.freedesktop.Telepathy.Channel
  */
 static void
-tpsip_text_channel_dbus_close (TpSvcChannel *iface,
-                               DBusGMethodInvocation *context)
+tpsip_text_channel_close (TpSvcChannel *iface,
+                          DBusGMethodInvocation *context)
 {
-  tpsip_text_channel_close (TPSIP_TEXT_CHANNEL(iface));
-  tp_svc_channel_return_from_close (context);
-}
+  TpsipTextChannel *self = TPSIP_TEXT_CHANNEL (iface);
+  TpsipTextChannelPrivate *priv = TPSIP_TEXT_CHANNEL_GET_PRIVATE(self);
 
-void
-tpsip_text_channel_close (TpsipTextChannel *self)
-{
-  TpsipTextChannelPrivate *priv;
+  if (priv->closed)
+    {
+      DEBUG ("already closed, doing nothing");
+    }
+  else
+    {
+      if (g_queue_is_empty (priv->pending_messages))
+        {
+          DEBUG ("actually closing, no pending messages");
+          priv->closed = TRUE;
+        }
+      else
+        {
+          DEBUG ("not really closing, there are pending messages left");
 
-  DEBUG("enter");
+          if (priv->initiator != priv->handle)
+            {
+              TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
+                  ((TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
 
-  priv = TPSIP_TEXT_CHANNEL_GET_PRIVATE(self);
-  if (!priv->closed)
-    {
-      priv->closed = TRUE;
+              g_assert (priv->initiator != 0);
+              g_assert (priv->handle != 0);
+
+              tp_handle_unref (contact_repo, priv->initiator);
+              priv->initiator = priv->handle;
+              tp_handle_ref (contact_repo, priv->initiator);
+            }
+
+          /* XXX: clear the queue of messages awaiting sent confirmation? */
+        }
       tp_svc_channel_emit_closed (self);
     }
+  tp_svc_channel_return_from_close (context);
 }
 
 /**
@@ -933,10 +955,9 @@ channel_iface_init(gpointer g_iface, gpointer iface_data)
 {
   TpSvcChannelClass *klass = (TpSvcChannelClass *)g_iface;
 
-  tp_svc_channel_implement_close (
-      klass, tpsip_text_channel_dbus_close);
 #define IMPLEMENT(x) tp_svc_channel_implement_##x (\
       klass, tpsip_text_channel_##x)
+  IMPLEMENT(close);
   IMPLEMENT(get_channel_type);
   IMPLEMENT(get_handle);
   IMPLEMENT(get_interfaces);
diff --git a/src/sip-text-channel.h b/src/sip-text-channel.h
index 1fc7cdb..e3db61b 100644
--- a/src/sip-text-channel.h
+++ b/src/sip-text-channel.h
@@ -58,9 +58,6 @@ GType tpsip_text_channel_get_type(void);
 #define TPSIP_TEXT_CHANNEL_GET_CLASS(obj) \
   (G_TYPE_INSTANCE_GET_CLASS ((obj), TPSIP_TYPE_TEXT_CHANNEL, TpsipTextChannelClass))
 
-
-void tpsip_text_channel_close (TpsipTextChannel *self);
-
 void tpsip_text_channel_receive (TpsipTextChannel  *obj,
                                  nua_handle_t      *nh,
                                  nua_saved_event_t *event,
diff --git a/src/text-factory.c b/src/text-factory.c
index 77c9aac..e8624db 100644
--- a/src/text-factory.c
+++ b/src/text-factory.c
@@ -149,15 +149,6 @@ tpsip_text_factory_class_init (TpsipTextFactoryClass *klass)
   g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
 }
 
-static gboolean
-tpsip_text_factory_close_one (gpointer key,
-                            gpointer data,
-                            gpointer user_data)
-{
-  tpsip_text_channel_close (TPSIP_TEXT_CHANNEL(data));
-  return TRUE;
-}
-
 static void
 tpsip_text_factory_close_all (TpChannelFactoryIface *iface)
 {
@@ -171,7 +162,7 @@ tpsip_text_factory_close_all (TpChannelFactoryIface *iface)
   channels = priv->channels;
   priv->channels = NULL;
 
-  g_hash_table_foreach_remove (channels, tpsip_text_factory_close_one, NULL);
+  g_hash_table_destroy (channels);
 }
 
 struct _ForeachData
@@ -213,12 +204,28 @@ channel_closed (TpsipTextChannel *chan, gpointer user_data)
   TpsipTextFactory *fac = TPSIP_TEXT_FACTORY (user_data);
   TpsipTextFactoryPrivate *priv = TPSIP_TEXT_FACTORY_GET_PRIVATE (fac);
   TpHandle contact_handle;
+  gboolean really_destroyed = TRUE;
 
-  g_object_get (chan, "handle", &contact_handle, NULL);
-  DEBUG("removing text channel with handle %u", contact_handle);
+  if (priv->channels == NULL)
+    return;
 
-  if (priv->channels)
-    g_hash_table_remove (priv->channels, GINT_TO_POINTER (contact_handle));
+  g_object_get (chan,
+      "handle", &contact_handle,
+      "channel-destroyed", &really_destroyed,
+      NULL);
+
+  if (really_destroyed)
+    {
+      DEBUG ("removing text channel with handle %u", contact_handle);
+      g_hash_table_remove (priv->channels, GINT_TO_POINTER (contact_handle));
+    }
+  else
+    {
+      DEBUG ("reopening channel with handle %u due to pending messages",
+             contact_handle);
+      tp_channel_factory_iface_emit_new_channel (
+          (TpChannelFactoryIface *) fac, (TpChannelIface *)chan, NULL);
+    }
 }
 
 /**
-- 
1.5.6.5




More information about the Telepathy-commits mailing list