[farsight2/master] Add STUN timeout, protect more variables with the mutex
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:19:37 PST 2008
---
transmitters/rawudp/fs-rawudp-stream-transmitter.c | 73 ++++++++++++++++++--
1 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/transmitters/rawudp/fs-rawudp-stream-transmitter.c b/transmitters/rawudp/fs-rawudp-stream-transmitter.c
index 0ef06b1..172f088 100644
--- a/transmitters/rawudp/fs-rawudp-stream-transmitter.c
+++ b/transmitters/rawudp/fs-rawudp-stream-transmitter.c
@@ -100,8 +100,11 @@ struct _FsRawUdpStreamTransmitterPrivate
guint stun_port;
guint stun_timeout;
+ /* These are protected by the sources_mutex too */
gulong stun_rtp_recv_id;
gulong stun_rtcp_recv_id;
+ guint stun_rtp_timeout_id;
+ guint stun_rtcp_timeout_id;
gchar stun_cookie[16];
@@ -258,12 +261,13 @@ fs_rawudp_stream_transmitter_dispose (GObject *object)
return;
}
+ g_mutex_lock (self->priv->sources_mutex);
if (self->priv->stun_rtp_recv_id)
fs_rawudp_stream_transmitter_stop_stun (self, FS_COMPONENT_RTP);
if (self->priv->stun_rtp_recv_id)
fs_rawudp_stream_transmitter_stop_stun (self, FS_COMPONENT_RTCP);
- g_mutex_lock (self->priv->sources_mutex);
+
if (self->priv->sources) {
g_list_foreach (self->priv->sources, (GFunc) g_source_remove, NULL);
g_list_free (self->priv->sources);
@@ -688,8 +692,10 @@ fs_rawudp_stream_transmitter_emit_stun_candidate (gpointer user_data)
g_signal_emit_by_name (data->self, "new-local-candidate", data->candidate);
/* Lets call it over if its over */
+ g_mutex_lock (data->self->priv->sources_mutex);
if (data->self->priv->stun_rtp_recv_id == 0 &&
data->self->priv->stun_rtcp_recv_id == 0 ) {
+ g_mutex_unlock (data->self->priv->sources_mutex);
fs_rawudp_stream_transmitter_finish_candidate_generation (data->self);
} else {
/* Lets remove this source from the list of sources to destroy */
@@ -698,11 +704,10 @@ fs_rawudp_stream_transmitter_emit_stun_candidate (gpointer user_data)
if (source) {
guint id = g_source_get_id (source);
- g_mutex_lock (data->self->priv->sources_mutex);
data->self->priv->sources =
g_list_remove (data->self->priv->sources, GUINT_TO_POINTER (id));
- g_mutex_unlock (data->self->priv->sources_mutex);
}
+ g_mutex_unlock (data->self->priv->sources_mutex);
}
fs_rawudp_stream_transmitter_maybe_new_active_candidate_pair (data->self,
@@ -764,14 +769,18 @@ fs_rawudp_stream_transmitter_stun_recv_cb (GstPad *pad, GstBuffer *buffer,
}
if (msg->type == STUN_MESSAGE_BINDING_ERROR_RESPONSE) {
+ fs_stream_transmitter_emit_error (FS_STREAM_TRANSMITTER (self),
+ FS_ERROR_NETWORK, "Got an error message from the STUN server",
+ "The STUN process produced an error");
stun_message_free (msg);
- fs_rawudp_stream_transmitter_stop_stun (self, component_id);
- /* FIXME: Return local candidate */
+ // fs_rawudp_stream_transmitter_stop_stun (self, component_id);
+ /* Lets not stop the STUN now and wait for the timeout
+ * in case the server answers with the right reply
+ */
return FALSE;
}
if (msg->type != STUN_MESSAGE_BINDING_RESPONSE) {
- /* Some other stun message */
stun_message_free (msg);
return TRUE;
}
@@ -808,7 +817,9 @@ fs_rawudp_stream_transmitter_stun_recv_cb (GstPad *pad, GstBuffer *buffer,
}
}
+ g_mutex_lock (self->priv->sources_mutex);
fs_rawudp_stream_transmitter_stop_stun (self, component_id);
+ g_mutex_unlock (self->priv->sources_mutex);
if (candidate) {
guint id;
@@ -829,6 +840,27 @@ fs_rawudp_stream_transmitter_stun_recv_cb (GstPad *pad, GstBuffer *buffer,
}
static gboolean
+fs_rawudp_stream_transmitter_stun_timeout_cb (gpointer user_data)
+{
+ struct CandidateTransit *data = user_data;
+
+
+ g_mutex_lock (data->self->priv->sources_mutex);
+
+ fs_rawudp_stream_transmitter_stop_stun (data->self, data->component_id);
+
+ if (data->self->priv->stun_rtp_recv_id == 0 &&
+ data->self->priv->stun_rtcp_recv_id == 0 ) {
+ g_mutex_unlock (data->self->priv->sources_mutex);
+ fs_rawudp_stream_transmitter_finish_candidate_generation (data->self);
+ } else {
+ g_mutex_unlock (data->self->priv->sources_mutex);
+ }
+
+ return FALSE;
+}
+
+static gboolean
fs_rawudp_stream_transmitter_start_stun (FsRawUdpStreamTransmitter *self,
guint component_id, GError **error)
{
@@ -841,6 +873,7 @@ fs_rawudp_stream_transmitter_start_stun (FsRawUdpStreamTransmitter *self,
StunMessage *msg;
gboolean ret = TRUE;
UdpPort *udpport;
+ struct CandidateTransit *data;
if (component_id == FS_COMPONENT_RTP)
udpport = self->priv->rtp_udpport;
@@ -869,6 +902,7 @@ fs_rawudp_stream_transmitter_start_stun (FsRawUdpStreamTransmitter *self,
address.sin_family = AF_INET;
address.sin_port = htons (self->priv->stun_port);
+ g_mutex_lock (self->priv->sources_mutex);
if (component_id == FS_COMPONENT_RTP)
self->priv->stun_rtp_recv_id =
fs_rawudp_transmitter_udpport_connect_recv (udpport,
@@ -877,6 +911,7 @@ fs_rawudp_stream_transmitter_start_stun (FsRawUdpStreamTransmitter *self,
self->priv->stun_rtcp_recv_id =
fs_rawudp_transmitter_udpport_connect_recv (udpport,
G_CALLBACK (fs_rawudp_stream_transmitter_stun_recv_cb), self);
+ g_mutex_unlock (self->priv->sources_mutex);
msg = stun_message_new (STUN_MESSAGE_BINDING_REQUEST,
self->priv->stun_cookie, 0);
@@ -897,9 +932,27 @@ fs_rawudp_stream_transmitter_start_stun (FsRawUdpStreamTransmitter *self,
g_free (packed);
stun_message_free (msg);
+ data = g_new0 (struct CandidateTransit, 1);
+ data->self = self;
+ data->component_id = component_id;
+
+ g_mutex_lock (data->self->priv->sources_mutex);
+ if (component_id == FS_COMPONENT_RTP)
+ self->priv->stun_rtp_timeout_id = g_timeout_add_seconds_full (
+ G_PRIORITY_DEFAULT,self->priv->stun_timeout,
+ fs_rawudp_stream_transmitter_stun_timeout_cb, data, g_free);
+ else if (component_id == FS_COMPONENT_RTCP)
+ self->priv->stun_rtcp_timeout_id = g_timeout_add_seconds_full (
+ G_PRIORITY_DEFAULT, self->priv->stun_timeout,
+ fs_rawudp_stream_transmitter_stun_timeout_cb, data, g_free);
+ g_mutex_unlock (data->self->priv->sources_mutex);
+
return ret;
}
+/*
+ * This function MUST be called with the sources_mutex held
+ */
static void
fs_rawudp_stream_transmitter_stop_stun (FsRawUdpStreamTransmitter *self,
@@ -911,6 +964,10 @@ fs_rawudp_stream_transmitter_stop_stun (FsRawUdpStreamTransmitter *self,
self->priv->stun_rtp_recv_id);
self->priv->stun_rtp_recv_id = 0;
}
+ if (self->priv->stun_rtp_timeout_id) {
+ g_source_remove (self->priv->stun_rtp_timeout_id);
+ self->priv->stun_rtp_timeout_id = 0;
+ }
}
else if (component_id == FS_COMPONENT_RTCP) {
if (self->priv->stun_rtcp_recv_id) {
@@ -918,6 +975,10 @@ fs_rawudp_stream_transmitter_stop_stun (FsRawUdpStreamTransmitter *self,
self->priv->stun_rtcp_recv_id);
self->priv->stun_rtcp_recv_id = 0;
}
+ if (self->priv->stun_rtcp_timeout_id) {
+ g_source_remove (self->priv->stun_rtcp_timeout_id);
+ self->priv->stun_rtcp_timeout_id = 0;
+ }
}
}
--
1.5.6.5
More information about the farsight-commits
mailing list