[Telepathy-commits] [telepathy-gabble/master] fix crash if content remove is acknowledged after session termination

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


---
 src/jingle-content.c |    3 +++
 src/jingle-session.c |    3 +++
 src/media-stream.c   |   13 ++++++++++++-
 3 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/src/jingle-content.c b/src/jingle-content.c
index 157ce17..8255ee8 100644
--- a/src/jingle-content.c
+++ b/src/jingle-content.c
@@ -900,6 +900,8 @@ _on_remove_reply (GabbleJingleSession *sess, gboolean success,
   g_assert (priv->state == JINGLE_CONTENT_STATE_REMOVING);
 
   g_signal_emit (c, signals[REMOVED], 0);
+
+  g_object_unref (c);
 }
 
 void
@@ -928,6 +930,7 @@ gabble_jingle_content_remove (GabbleJingleContent *c, gboolean signal_peer)
       msg = gabble_jingle_session_new_message (c->session,
           JINGLE_ACTION_CONTENT_REMOVE, &sess_node);
       gabble_jingle_content_produce_node (c, sess_node, FALSE);
+      g_object_ref (c);
       gabble_jingle_session_send (c->session, msg, _on_remove_reply, c);
     }
   else
diff --git a/src/jingle-session.c b/src/jingle-session.c
index d74d0e4..5bed855 100644
--- a/src/jingle-session.c
+++ b/src/jingle-session.c
@@ -1480,6 +1480,9 @@ content_removed_cb (GabbleJingleContent *c, gpointer user_data)
   g_object_get (c, "name", &name, NULL);
   g_hash_table_remove (priv->contents, name);
 
+  if (priv->state == JS_STATE_ENDED)
+      return;
+
   if (count_active_contents (sess) == 0)
     {
       /* Terminate the session from idle loop
diff --git a/src/media-stream.c b/src/media-stream.c
index 3e12cb8..0e591f7 100644
--- a/src/media-stream.c
+++ b/src/media-stream.c
@@ -114,6 +114,9 @@ struct _GabbleMediaStreamPrivate
 
   guint remote_candidate_count;
 
+  /* signal handler ID for content REMOVED signal */
+  gboolean removed_id;
+
   /* These are really booleans, but gboolean is signed. Thanks, GLib */
   unsigned closed:1;
   unsigned dispose_has_run:1;
@@ -358,7 +361,7 @@ gabble_media_stream_set_property (GObject      *object,
       g_signal_connect (priv->content, "notify::senders",
           (GCallback) content_senders_changed_cb, stream);
 
-      g_signal_connect (priv->content, "removed",
+      priv->removed_id = g_signal_connect (priv->content, "removed",
           (GCallback) content_removed_cb, stream);
 
       /* we can immediately get the codecs if we're responder */
@@ -634,6 +637,14 @@ gabble_media_stream_dispose (GObject *object)
 
   priv->dispose_has_run = TRUE;
 
+  /* If content wasn't removed already, it will emit REMOVED signal
+   * later on. We don't want to catch that. */
+  if (priv->removed_id)
+    {
+      g_signal_handler_disconnect (priv->content, priv->removed_id);
+      priv->removed_id = 0;
+    }
+
   if (G_OBJECT_CLASS (gabble_media_stream_parent_class)->dispose)
     G_OBJECT_CLASS (gabble_media_stream_parent_class)->dispose (object);
 }
-- 
1.5.6.5




More information about the Telepathy-commits mailing list