[farsight2/master] Make multicast stream transmitter code re-entrant
Olivier Crête
olivier.crete at collabora.co.uk
Sun Dec 28 21:38:51 PST 2008
---
.../multicast/fs-multicast-stream-transmitter.c | 43 +++++++++++++++++--
transmitters/multicast/fs-multicast-transmitter.c | 9 ++++
transmitters/multicast/fs-multicast-transmitter.h | 3 +
3 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/transmitters/multicast/fs-multicast-stream-transmitter.c b/transmitters/multicast/fs-multicast-stream-transmitter.c
index b62883a..5b7ebb4 100644
--- a/transmitters/multicast/fs-multicast-stream-transmitter.c
+++ b/transmitters/multicast/fs-multicast-stream-transmitter.c
@@ -108,14 +108,19 @@ struct _FsMulticastStreamTransmitterPrivate
*/
FsMulticastTransmitter *transmitter;
+ GMutex *mutex;
+
+ /* Protected by the mutex */
gboolean sending;
/*
* We have at most of those per component (index 0 is unused)
*/
- FsCandidate **remote_candidate;
FsCandidate **local_candidate;
+ /* Protected by the mutex */
+ FsCandidate **remote_candidate;
+ /* Protected by the mutex */
UdpSock **udpsocks;
GList *preferred_local_candidates;
@@ -125,6 +130,11 @@ struct _FsMulticastStreamTransmitterPrivate
(G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_MULTICAST_STREAM_TRANSMITTER, \
FsMulticastStreamTransmitterPrivate))
+#define FS_MULTICAST_STREAM_TRANSMITTER_LOCK(s) \
+ g_mutex_lock ((s)->priv->mutex)
+#define FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK(s) \
+ g_mutex_unlock ((s)->priv->mutex)
+
static void fs_multicast_stream_transmitter_class_init (FsMulticastStreamTransmitterClass *klass);
static void fs_multicast_stream_transmitter_init (FsMulticastStreamTransmitter *self);
static void fs_multicast_stream_transmitter_dispose (GObject *object);
@@ -209,6 +219,8 @@ fs_multicast_stream_transmitter_init (FsMulticastStreamTransmitter *self)
self->priv->disposed = FALSE;
self->priv->sending = TRUE;
+
+ self->priv->mutex = g_mutex_new ();
}
static void
@@ -296,7 +308,9 @@ fs_multicast_stream_transmitter_get_property (GObject *object,
switch (prop_id)
{
case PROP_SENDING:
+ FS_MULTICAST_STREAM_TRANSMITTER_LOCK (self);
g_value_set_boolean (value, self->priv->sending);
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
break;
case PROP_PREFERRED_LOCAL_CANDIDATES:
g_value_set_boxed (value, self->priv->preferred_local_candidates);
@@ -319,21 +333,32 @@ fs_multicast_stream_transmitter_set_property (GObject *object,
case PROP_SENDING:
{
gboolean old_sending = self->priv->sending;
+ gboolean sending = g_value_get_boolean (value);
gint c;
- self->priv->sending = g_value_get_boolean (value);
+ FS_MULTICAST_STREAM_TRANSMITTER_LOCK (self);
+ self->priv->sending = sending;
- if (self->priv->sending != old_sending)
+ if (sending != old_sending)
for (c = 1; c <= self->priv->transmitter->components; c++)
if (self->priv->udpsocks[c])
{
- if (self->priv->sending)
+ guint8 ttl = self->priv->remote_candidate[c]->ttl;
+ fs_multicast_transmitter_udpsock_ref (self->priv->transmitter,
+ self->priv->udpsocks[c], ttl);
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
+ if (sending)
fs_multicast_transmitter_udpsock_inc_sending (
self->priv->udpsocks[c]);
else
fs_multicast_transmitter_udpsock_dec_sending (
self->priv->udpsocks[c]);
+ fs_multicast_transmitter_put_udpsock (self->priv->transmitter,
+ self->priv->udpsocks[c], ttl);
+ FS_MULTICAST_STREAM_TRANSMITTER_LOCK (self);
}
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
+
}
break;
case PROP_PREFERRED_LOCAL_CANDIDATES:
@@ -432,6 +457,7 @@ fs_multicast_stream_transmitter_add_remote_candidate (
{
UdpSock *newudpsock = NULL;
+ FS_MULTICAST_STREAM_TRANSMITTER_LOCK (self);
if (self->priv->remote_candidate[candidate->component_id])
{
FsCandidate *old_candidate =
@@ -441,10 +467,13 @@ fs_multicast_stream_transmitter_add_remote_candidate (
!strcmp (old_candidate->ip, candidate->ip))
{
GST_DEBUG ("Re-set the same candidate, ignoring");
- return TRUE;
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
+ return TRUE;
}
}
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
+
/*
* IMPROVE ME: We should probably check that the candidate's IP
* has the format x.x.x.x where x is [0,255] using GRegex, etc
@@ -463,6 +492,8 @@ fs_multicast_stream_transmitter_add_remote_candidate (
if (!newudpsock)
return FALSE;
+ FS_MULTICAST_STREAM_TRANSMITTER_LOCK (self);
+
if (self->priv->udpsocks[candidate->component_id])
{
if (self->priv->sending)
@@ -483,6 +514,8 @@ fs_multicast_stream_transmitter_add_remote_candidate (
self->priv->remote_candidate[candidate->component_id] =
fs_candidate_copy (candidate);
+ FS_MULTICAST_STREAM_TRANSMITTER_UNLOCK (self);
+
g_signal_emit_by_name (self, "new-active-candidate-pair",
self->priv->local_candidate[candidate->component_id],
self->priv->remote_candidate[candidate->component_id]);
diff --git a/transmitters/multicast/fs-multicast-transmitter.c b/transmitters/multicast/fs-multicast-transmitter.c
index 538a788..d6ffda5 100644
--- a/transmitters/multicast/fs-multicast-transmitter.c
+++ b/transmitters/multicast/fs-multicast-transmitter.c
@@ -1005,3 +1005,12 @@ fs_multicast_transmitter_get_stream_transmitter_type (
{
return FS_TYPE_MULTICAST_STREAM_TRANSMITTER;
}
+
+void
+fs_multicast_transmitter_udpsock_ref (FsMulticastTransmitter *trans,
+ UdpSock *udpsock, guint8 ttl)
+{
+ g_mutex_lock (trans->priv->mutex);
+ g_byte_array_append (udpsock->ttls, &ttl, 1);
+ g_mutex_unlock (trans->priv->mutex);
+}
diff --git a/transmitters/multicast/fs-multicast-transmitter.h b/transmitters/multicast/fs-multicast-transmitter.h
index 9b4b9b1..c712bde 100644
--- a/transmitters/multicast/fs-multicast-transmitter.h
+++ b/transmitters/multicast/fs-multicast-transmitter.h
@@ -101,6 +101,9 @@ void fs_multicast_transmitter_put_udpsock (FsMulticastTransmitter *trans,
void fs_multicast_transmitter_udpsock_inc_sending (UdpSock *udpsock);
void fs_multicast_transmitter_udpsock_dec_sending (UdpSock *udpsock);
+void fs_multicast_transmitter_udpsock_ref (FsMulticastTransmitter *trans,
+ UdpSock *udpsock, guint8 ttl);
+
G_END_DECLS
--
1.5.6.5
More information about the farsight-commits
mailing list