[farsight2/master] Protect streamtransmitter in stream against early dispose
Olivier Crête
olivier.crete at collabora.co.uk
Wed Jan 7 17:25:23 PST 2009
---
gst/fsrtpconference/fs-rtp-stream.c | 99 ++++++++++++++++++++++++++++-------
1 files changed, 79 insertions(+), 20 deletions(-)
diff --git a/gst/fsrtpconference/fs-rtp-stream.c b/gst/fsrtpconference/fs-rtp-stream.c
index a562de1..f004508 100644
--- a/gst/fsrtpconference/fs-rtp-stream.c
+++ b/gst/fsrtpconference/fs-rtp-stream.c
@@ -221,6 +221,30 @@ fs_rtp_stream_get_session (FsRtpStream *self, GError **error)
return session;
}
+
+static FsStreamTransmitter *
+fs_rtp_stream_get_stream_transmitter (FsRtpStream *self, GError **error)
+{
+ FsRtpSession *session = fs_rtp_stream_get_session (self, error);
+ FsStreamTransmitter *st = NULL;
+
+ if (!session)
+ return NULL;
+
+ FS_RTP_SESSION_LOCK (session);
+ st = self->priv->stream_transmitter;
+ if (st)
+ g_object_ref (st);
+ FS_RTP_SESSION_UNLOCK (session);
+
+ if (!st)
+ g_set_error (error, FS_ERROR, FS_ERROR_DISPOSED,
+ "Called function after stream has been disposed");
+
+ g_object_unref (session);
+ return st;
+}
+
static void
fs_rtp_stream_dispose (GObject *object)
{
@@ -368,12 +392,8 @@ fs_rtp_stream_set_property (GObject *object,
GParamSpec *pspec)
{
FsRtpStream *self = FS_RTP_STREAM (object);
- FsRtpSession *session = fs_rtp_stream_get_session (self, NULL);
GList *item;
- if (!session)
- return;
-
switch (prop_id) {
case PROP_SESSION:
self->priv->session = FS_RTP_SESSION (g_value_dup_object (value));
@@ -386,25 +406,48 @@ fs_rtp_stream_set_property (GObject *object,
FS_STREAM_TRANSMITTER (g_value_get_object (value));
break;
case PROP_DIRECTION:
- self->priv->direction = g_value_get_flags (value);
- if (self->priv->stream_transmitter)
- g_object_set (self->priv->stream_transmitter, "sending",
- self->priv->direction & FS_DIRECTION_SEND, NULL);
- FS_RTP_SESSION_LOCK (session);
- for (item = g_list_first (self->substreams);
- item;
- item = g_list_next (item))
- g_object_set (G_OBJECT (item->data),
- "receiving", ((self->priv->direction & FS_DIRECTION_RECV) != 0),
- NULL);
- FS_RTP_SESSION_UNLOCK (session);
+ {
+ FsStreamTransmitter *st = NULL;
+ GList *copy = NULL;
+ FsRtpSession *session = fs_rtp_stream_get_session (self, NULL);
+ FsStreamDirection dir;
+
+ if (!session)
+ {
+ self->priv->direction = g_value_get_flags (value);
+ return;
+ }
+
+ FS_RTP_SESSION_LOCK (session);
+ dir = self->priv->direction = g_value_get_flags (value);
+ FS_RTP_SESSION_UNLOCK (session);
+ st = fs_rtp_stream_get_stream_transmitter (self, NULL);
+ if (st)
+ {
+ g_object_set (self->priv->stream_transmitter, "sending",
+ dir & FS_DIRECTION_SEND, NULL);
+ g_object_unref (st);
+ }
+
+ FS_RTP_SESSION_LOCK (session);
+ copy = g_list_copy (g_list_first (self->substreams));
+ g_list_foreach (copy, (GFunc) g_object_ref, NULL);
+ FS_RTP_SESSION_UNLOCK (session);
+
+ for (item = copy; item; item = g_list_next (item))
+ g_object_set (G_OBJECT (item->data),
+ "receiving", ((dir & FS_DIRECTION_RECV) != 0),
+ NULL);
+ g_list_foreach (copy, (GFunc) g_object_unref, NULL);
+ g_list_free (copy);
+ g_object_unref (session);
+ }
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
- g_object_unref (session);
}
static void
@@ -470,9 +513,16 @@ fs_rtp_stream_set_remote_candidates (FsStream *stream, GList *candidates,
GError **error)
{
FsRtpStream *self = FS_RTP_STREAM (stream);
+ FsStreamTransmitter *st = fs_rtp_stream_get_stream_transmitter (self, error);
+ gboolean ret = FALSE;
+
+ if (!st)
+ return FALSE;
+
+ ret = fs_stream_transmitter_set_remote_candidates (st, candidates, error);
- return fs_stream_transmitter_set_remote_candidates (
- self->priv->stream_transmitter, candidates, error);
+ g_object_unref (st);
+ return ret;
}
/**
@@ -488,10 +538,19 @@ fs_rtp_stream_force_remote_candidates (FsStream *stream,
GError **error)
{
FsRtpStream *self = FS_RTP_STREAM (stream);
+ FsStreamTransmitter *st = fs_rtp_stream_get_stream_transmitter (self, error);
+ gboolean ret = FALSE;
+
+ if (!st)
+ return FALSE;
- return fs_stream_transmitter_force_remote_candidates (
+
+ ret = fs_stream_transmitter_force_remote_candidates (
self->priv->stream_transmitter, remote_candidates,
error);
+
+ g_object_unref (st);
+ return ret;
}
--
1.5.6.5
More information about the farsight-commits
mailing list