[Telepathy-commits] [telepathy-gabble/master] Ignore Google relay responses when session dies
Will Thompson
will.thompson at collabora.co.uk
Fri Mar 20 06:11:53 PDT 2009
This fixes fd.o #20764.
Reviewed-by: Simon McVittie <simon.mcvittie at collabora.co.uk>
---
src/media-channel.c | 28 ++++++++++++++++++++++
tests/twisted/jingle/google-relay.py | 42 +++++++++++++++++++++++++++++-----
2 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/src/media-channel.c b/src/media-channel.c
index f76a913..8baf9db 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -152,6 +152,9 @@ struct _GabbleMediaChannelPrivate
/* list of PendingStreamRequest* in no particular order */
GList *pending_stream_requests;
+ /* list of StreamCreationData* in no particular order */
+ GList *stream_creation_datas;
+
guint next_stream_id;
TpLocalHoldState hold_state;
@@ -202,6 +205,7 @@ static void create_stream_from_content (GabbleMediaChannel *chan,
GabbleJingleContent *c);
static gboolean contact_is_media_capable (GabbleMediaChannel *chan, TpHandle peer,
gboolean *wait);
+static void stream_creation_data_cancel (gpointer p, gpointer unused);
static void
_create_streams (GabbleMediaChannel *chan)
@@ -735,6 +739,11 @@ gabble_media_channel_dispose (GObject *object)
priv->dispose_has_run = TRUE;
+ /* StreamCreationData * holds a reference to the media channel; thus, we
+ * shouldn't be disposed till they've all gone away.
+ */
+ g_assert (priv->stream_creation_datas == NULL);
+
if (priv->delayed_request_streams != NULL)
{
g_ptr_array_foreach (priv->delayed_request_streams,
@@ -2051,6 +2060,10 @@ session_terminated_cb (GabbleJingleSession *session,
TP_CHANNEL_GROUP_FLAG_CAN_ADD,
TP_CHANNEL_GROUP_FLAG_CAN_REMOVE);
+ /* Ignore any Google relay session responses we're waiting for. */
+ g_list_foreach (priv->stream_creation_datas, stream_creation_data_cancel,
+ NULL);
+
/* any contents that we were waiting for have now lost */
g_list_foreach (priv->pending_stream_requests,
(GFunc) pending_stream_request_free, NULL);
@@ -2548,9 +2561,19 @@ typedef struct {
} StreamCreationData;
static void
+stream_creation_data_cancel (gpointer p,
+ gpointer unused)
+{
+ StreamCreationData *d = p;
+
+ d->content = NULL;
+}
+
+static void
stream_creation_data_free (gpointer p)
{
StreamCreationData *d = p;
+ GabbleMediaChannelPrivate *priv = d->self->priv;
g_free (d->name);
g_free (d->nat_traversal);
@@ -2561,6 +2584,8 @@ stream_creation_data_free (gpointer p)
g_object_unref (d->content);
}
+ priv->stream_creation_datas = g_list_remove (priv->stream_creation_datas, d);
+
g_object_unref (d->self);
g_slice_free (StreamCreationData, d);
}
@@ -2675,6 +2700,9 @@ create_stream_from_content (GabbleMediaChannel *self,
g_idle_add_full (G_PRIORITY_DEFAULT, construct_stream_later_cb,
d, stream_creation_data_free);
}
+
+ self->priv->stream_creation_datas = g_list_prepend (
+ self->priv->stream_creation_datas, d);
}
static void
diff --git a/tests/twisted/jingle/google-relay.py b/tests/twisted/jingle/google-relay.py
index 078a253..519ad0e 100644
--- a/tests/twisted/jingle/google-relay.py
+++ b/tests/twisted/jingle/google-relay.py
@@ -4,8 +4,8 @@ Test getting relay from Google jingleinfo
from gabbletest import exec_test, make_result_iq, sync_stream, \
GoogleXmlStream
-from servicetest import make_channel_proxy, unwrap, tp_path_prefix, \
- EventPattern, call_async
+from servicetest import make_channel_proxy, tp_path_prefix, \
+ EventPattern, call_async, sync_dbus
import jingletest
import gabbletest
import constants as c
@@ -68,7 +68,7 @@ magic_cookie=MMMMMMMM
""" % (http_req, http_req))
http_req += 1
-def test(q, bus, conn, stream, incoming=True):
+def test(q, bus, conn, stream, incoming=True, too_slow=False):
jt = jingletest.JingleTest(stream, 'test at localhost', 'foo at bar.com/Foo')
# If we need to override remote caps, feats, codecs or caps,
@@ -154,6 +154,9 @@ def test(q, bus, conn, stream, incoming=True):
# We're pending because of remote_handle
e = q.expect('dbus-signal', signal='MembersChanged',
args=[u'', [], [], [1L], [], remote_handle, 0])
+
+ media_chan = make_channel_proxy(conn, tp_path_prefix + e.path,
+ 'Channel.Interface.Group')
else:
call_async(q, conn.Requests, 'CreateChannel',
{ 'org.freedesktop.Telepathy.Channel.ChannelType':
@@ -168,6 +171,7 @@ def test(q, bus, conn, stream, incoming=True):
EventPattern('dbus-signal', signal='NewChannels'),
)
path = ret.value[0]
+ media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
media_iface = make_channel_proxy(conn, path,
'Channel.Type.StreamedMedia')
call_async(q, media_iface, 'RequestStreams',
@@ -177,6 +181,10 @@ def test(q, bus, conn, stream, incoming=True):
e = q.expect('dbus-signal', signal='NewSessionHandler')
assert e.args[1] == 'rtp'
+ if too_slow:
+ test_too_slow(q, bus, conn, stream, httpd, media_chan)
+ return
+
# In response to the streams call, we now have two HTTP requests
# (for RTP and RTCP)
httpd.handle_request()
@@ -192,8 +200,6 @@ def test(q, bus, conn, stream, incoming=True):
e = q.expect('dbus-signal', signal='NewStreamHandler')
stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
- media_chan = make_channel_proxy(conn, tp_path_prefix + e.path, 'Channel.Interface.Group')
-
# Exercise channel properties
channel_props = media_chan.GetAll(
'org.freedesktop.Telepathy.Channel',
@@ -301,7 +307,25 @@ def test(q, bus, conn, stream, incoming=True):
conn.Disconnect()
q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])
- return True
+def test_too_slow(q, bus, conn, stream, httpd, media_chan):
+ """
+ Regression test for a bug where if the channel was closed before the HTTP
+ responses arrived, the responses finally arriving crashed Gabble.
+ """
+
+ # User gets bored, and closes the channel.
+ call_async(q, media_chan, 'Close', dbus_interface=c.CHANNEL)
+ q.expect('dbus-signal', signal='Closed')
+
+ # Now Google answers!
+ httpd.handle_request()
+ httpd.handle_request()
+
+ # Make a misc method call to check that Gabble's still alive.
+ sync_dbus(bus, q, conn)
+
+ conn.Disconnect()
+ q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])
if __name__ == '__main__':
@@ -309,3 +333,9 @@ if __name__ == '__main__':
protocol=GoogleXmlStream)
exec_test(lambda q, b, c, s: test(q, b, c, s, incoming=False),
protocol=GoogleXmlStream)
+ exec_test(lambda q, b, c, s: test(q, b, c, s, incoming=True,
+ too_slow=True),
+ protocol=GoogleXmlStream)
+ exec_test(lambda q, b, c, s: test(q, b, c, s, incoming=False,
+ too_slow=True),
+ protocol=GoogleXmlStream)
--
1.5.6.5
More information about the telepathy-commits
mailing list