[Telepathy-commits] [telepathy-gabble/master] refactored and simplified content removal code

Senko Rasic senko at phyrexia.lan
Tue Dec 2 04:34:02 PST 2008


---
 src/jingle-content.c |   10 ++++++--
 src/jingle-content.h |    2 +-
 src/jingle-session.c |   59 ++++++++++++++++++++++++++++++-------------------
 3 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/src/jingle-content.c b/src/jingle-content.c
index c571c2f..157ce17 100644
--- a/src/jingle-content.c
+++ b/src/jingle-content.c
@@ -903,12 +903,14 @@ _on_remove_reply (GabbleJingleSession *sess, gboolean success,
 }
 
 void
-gabble_jingle_content_remove (GabbleJingleContent *c)
+gabble_jingle_content_remove (GabbleJingleContent *c, gboolean signal_peer)
 {
   GabbleJingleContentPrivate *priv = GABBLE_JINGLE_CONTENT_GET_PRIVATE (c);
   LmMessage *msg;
   LmMessageNode *sess_node;
 
+  DEBUG ("called for content %s", priv->name);
+
   if (priv->state == JINGLE_CONTENT_STATE_REMOVING)
     {
       DEBUG ("ignoring request to remove content which is already being removed");
@@ -918,8 +920,10 @@ gabble_jingle_content_remove (GabbleJingleContent *c)
   priv->state = JINGLE_CONTENT_STATE_REMOVING;
   g_object_notify ((GObject *) c, "state");
 
-  /* If we were already signalled, we have to signal removal to the peer. */
-  if (priv->state != JINGLE_CONTENT_STATE_EMPTY)
+  /* If we were already signalled and removal is not a side-effect of
+   * something else (sesssion termination, or removal by peer),
+   * we have to signal removal to the peer. */
+  if (signal_peer && (priv->state != JINGLE_CONTENT_STATE_EMPTY))
     {
       msg = gabble_jingle_session_new_message (c->session,
           JINGLE_ACTION_CONTENT_REMOVE, &sess_node);
diff --git a/src/jingle-content.h b/src/jingle-content.h
index 116b8dc..b8731a0 100644
--- a/src/jingle-content.h
+++ b/src/jingle-content.h
@@ -108,7 +108,7 @@ void _gabble_jingle_content_set_media_ready (GabbleJingleContent *self);
 gboolean gabble_jingle_content_is_ready (GabbleJingleContent *self);
 void gabble_jingle_content_set_transport_state (GabbleJingleContent *content,
     JingleTransportState state);
-void gabble_jingle_content_remove (GabbleJingleContent *c);
+void gabble_jingle_content_remove (GabbleJingleContent *c, gboolean signal_peer);
 GList *gabble_jingle_content_get_remote_candidates (GabbleJingleContent *c);
 gboolean gabble_jingle_content_change_direction (GabbleJingleContent *c,
     JingleContentSenders senders);
diff --git a/src/jingle-session.c b/src/jingle-session.c
index b92e958..d74d0e4 100644
--- a/src/jingle-session.c
+++ b/src/jingle-session.c
@@ -662,10 +662,7 @@ _each_content_remove (GabbleJingleSession *sess, GabbleJingleContent *c,
       return;
     }
 
-  g_object_set (c, "state", JINGLE_CONTENT_STATE_REMOVING, NULL);
-  /* FIXME: we emit "removed" on GabbleJingleContent object, is this
-   * too hackish? */
-  g_signal_emit_by_name (c, "removed");
+  gabble_jingle_content_remove (c, FALSE);
 }
 
 static void
@@ -1447,6 +1444,31 @@ _terminate_delayed (gpointer user_data)
 }
 
 static void
+_foreach_count_active_contents (gpointer key, gpointer value, gpointer user_data)
+{
+  GabbleJingleContent *c = value;
+  guint *n_contents = user_data;
+  JingleContentState state;
+
+  g_object_get (c, "state", &state, NULL);
+  if ((state > JINGLE_CONTENT_STATE_NEW) &&
+      (state < JINGLE_CONTENT_STATE_REMOVING))
+    {
+      *n_contents = *n_contents + 1;
+    }
+}
+
+static gboolean
+count_active_contents (GabbleJingleSession *sess)
+{
+  GabbleJingleSessionPrivate *priv = GABBLE_JINGLE_SESSION_GET_PRIVATE (sess);
+  guint n_contents = 0;
+
+  g_hash_table_foreach (priv->contents, _foreach_count_active_contents, &n_contents);
+  return n_contents;
+}
+
+static void
 content_removed_cb (GabbleJingleContent *c, gpointer user_data)
 {
   GabbleJingleSession *sess = GABBLE_JINGLE_SESSION (user_data);
@@ -1458,7 +1480,7 @@ content_removed_cb (GabbleJingleContent *c, gpointer user_data)
   g_object_get (c, "name", &name, NULL);
   g_hash_table_remove (priv->contents, name);
 
-  if (g_hash_table_size (priv->contents) == 0)
+  if (count_active_contents (sess) == 0)
     {
       /* Terminate the session from idle loop
        * so that content removal can be processed
@@ -1467,30 +1489,21 @@ content_removed_cb (GabbleJingleContent *c, gpointer user_data)
     }
 }
 
+
 void
 gabble_jingle_session_remove_content (GabbleJingleSession *sess,
     GabbleJingleContent *c)
 {
-  GabbleJingleSessionPrivate *priv = GABBLE_JINGLE_SESSION_GET_PRIVATE (sess);
-
-  DEBUG ("called");
-
-  /* If this is the last content, instead of removing it we can just
-   * terminate the entire session. */
-  if (g_hash_table_size (priv->contents) == 1)
+  if (count_active_contents (sess) > 1)
     {
-      /* We'll fake the content removal signal, so both we and media
-       * channel clean up after it properly. */
-      // gabble_jingle_session_terminate (sess);
-      DEBUG ("manually removing content %p and emitting the signal", c);
-      g_object_set (c, "state", JINGLE_CONTENT_STATE_REMOVING, NULL);
-      g_signal_emit_by_name (c, "removed");
-      return;
+      gabble_jingle_content_remove (c, TRUE);
+    }
+  else
+    {
+      /* session will be terminated when the content gets maked as removed */
+      DEBUG ("called for last active content, doing session-terminate instead");
+      gabble_jingle_content_remove (c, FALSE);
     }
-
-  /* When content-remove is acknowledged, "removed" signal will be fired,
-   * so we can clean up. */
-  gabble_jingle_content_remove (c);
 }
 
 GabbleJingleContent *
-- 
1.5.6.5




More information about the Telepathy-commits mailing list