[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