Commit 2faa76a4 authored by Youness Alaoui's avatar Youness Alaoui

Use a global mutex for all nice agents and use g_source_is_destroyed to avoid...

Use a global mutex for all nice agents and use g_source_is_destroyed to avoid the race condition of a source being destroyed while we wait for the mutex
parent 7762ac11
......@@ -109,7 +109,6 @@ struct _NiceAgent
GSList *refresh_list; /* list of CandidateRefresh items */
guint64 tie_breaker; /* tie breaker (ICE sect 5.2
"Determining Role" ID-19) */
GStaticRecMutex mutex; /* Mutex used for thread-safe lib */
NiceCompatibility compatibility; /* property: Compatibility mode */
StunAgent stun_agent; /* STUN agent */
gboolean media_after_tick; /* Received media after keepalive tick */
......@@ -136,6 +135,9 @@ Stream *agent_find_stream (NiceAgent *agent, guint stream_id);
void agent_gathering_done (NiceAgent *agent);
void agent_signal_gathering_done (NiceAgent *agent);
void agent_lock (void);
void agent_unlock (void);
void agent_signal_new_selected_pair (
NiceAgent *agent,
guint stream_id,
......
This diff is collapsed.
......@@ -450,12 +450,17 @@ static gboolean priv_conn_check_tick_unlocked (gpointer pointer)
static gboolean priv_conn_check_tick (gpointer pointer)
{
NiceAgent *agent = pointer;
gboolean ret;
g_static_rec_mutex_lock (&agent->mutex);
agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_conn_check_tick");
agent_unlock ();
return FALSE;
}
ret = priv_conn_check_tick_unlocked (pointer);
g_static_rec_mutex_unlock (&agent->mutex);
agent_unlock();
return ret;
}
......@@ -464,14 +469,16 @@ static gboolean priv_conn_keepalive_retransmissions_tick (gpointer pointer)
{
CandidatePair *pair = (CandidatePair *) pointer;
g_static_rec_mutex_lock (&pair->keepalive.agent->mutex);
agent_lock();
/* A race condition might happen where the mutex above waits for the lock
* and in the meantime another thread destroys the source.
* In that case, we don't need to run our retransmission tick since it should
* have been cancelled */
if (pair->keepalive.tick_source == NULL) {
g_static_rec_mutex_unlock (&pair->keepalive.agent->mutex);
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_conn_keepalive_retransmissions_tick");
agent_unlock ();
return FALSE;
}
......@@ -532,7 +539,7 @@ static gboolean priv_conn_keepalive_retransmissions_tick (gpointer pointer)
}
g_static_rec_mutex_unlock (&pair->keepalive.agent->mutex);
agent_unlock ();
return FALSE;
}
......@@ -676,7 +683,14 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer)
NiceAgent *agent = pointer;
gboolean ret;
g_static_rec_mutex_lock (&agent->mutex);
agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_conn_keepalive_tick");
agent_unlock ();
return FALSE;
}
ret = priv_conn_keepalive_tick_unlocked (agent);
if (ret == FALSE) {
if (agent->keepalive_timer_source) {
......@@ -685,7 +699,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer)
agent->keepalive_timer_source = NULL;
}
}
g_static_rec_mutex_unlock (&agent->mutex);
agent_unlock();
return ret;
}
......@@ -694,17 +708,20 @@ static gboolean priv_turn_allocate_refresh_retransmissions_tick (gpointer pointe
{
CandidateRefresh *cand = (CandidateRefresh *) pointer;
g_static_rec_mutex_lock (&cand->agent->mutex);
agent_lock();
/* A race condition might happen where the mutex above waits for the lock
* and in the meantime another thread destroys the source.
* In that case, we don't need to run our retransmission tick since it should
* have been cancelled */
if (cand->tick_source == NULL) {
g_static_rec_mutex_unlock (&cand->agent->mutex);
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_turn_allocate_refresh_retransmissions_tick");
agent_unlock ();
return FALSE;
}
g_source_destroy (cand->tick_source);
g_source_unref (cand->tick_source);
cand->tick_source = NULL;
......@@ -738,7 +755,7 @@ static gboolean priv_turn_allocate_refresh_retransmissions_tick (gpointer pointe
}
g_static_rec_mutex_unlock (&cand->agent->mutex);
agent_unlock ();
return FALSE;
}
......@@ -810,9 +827,16 @@ static gboolean priv_turn_allocate_refresh_tick (gpointer pointer)
{
CandidateRefresh *cand = (CandidateRefresh *) pointer;
g_static_rec_mutex_lock (&cand->agent->mutex);
agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_turn_allocate_refresh_tick");
agent_unlock ();
return FALSE;
}
priv_turn_allocate_refresh_tick_unlocked (cand);
g_static_rec_mutex_unlock (&cand->agent->mutex);
agent_unlock ();
return FALSE;
}
......
......@@ -1044,7 +1044,14 @@ static gboolean priv_discovery_tick (gpointer pointer)
NiceAgent *agent = pointer;
gboolean ret;
g_static_rec_mutex_lock (&agent->mutex);
agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in priv_discovery_tick");
agent_unlock ();
return FALSE;
}
ret = priv_discovery_tick_unlocked (pointer);
if (ret == FALSE) {
if (agent->discovery_timer_source != NULL) {
......@@ -1053,7 +1060,7 @@ static gboolean priv_discovery_tick (gpointer pointer)
agent->discovery_timer_source = NULL;
}
}
g_static_rec_mutex_unlock (&agent->mutex);
agent_unlock();
return ret;
}
......
......@@ -11,7 +11,8 @@ ERROR_CFLAGS = \
-Wmissing-prototypes \
-Wstrict-prototypes \
-Wredundant-decls \
-Wno-unused-parameter
-Wno-unused-parameter \
-Wno-missing-field-initializers
# -Wold-style-definition -Winline -Wunreachable-code
CLEANFILES = *.gcno *.gcda
......
......@@ -299,7 +299,14 @@ socket_send_more (
TcpPriv *priv = sock->priv;
struct to_be_sent *tbs = NULL;
g_static_rec_mutex_lock (&priv->agent->mutex);
agent_lock ();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in tcp-bsd.c:socket_send_more");
agent_unlock ();
return FALSE;
}
while ((tbs = g_queue_pop_head (&priv->send_queue)) != NULL) {
int ret;
......@@ -335,11 +342,11 @@ socket_send_more (
g_source_unref (priv->io_source);
priv->io_source = NULL;
g_static_rec_mutex_unlock (&priv->agent->mutex);
agent_unlock ();
return FALSE;
}
g_static_rec_mutex_unlock (&priv->agent->mutex);
agent_unlock ();
return TRUE;
}
......
......@@ -346,16 +346,15 @@ static gboolean
priv_forget_send_request (gpointer pointer)
{
SendRequest *req = pointer;
GStaticRecMutex *mutex = NULL;
if (req->priv == NULL)
return FALSE;
g_atomic_int_inc (&req->ref);
agent_lock ();
mutex = &req->priv->nice->mutex;
g_static_rec_mutex_lock (mutex);
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in turn.c:priv_forget_send_request");
agent_unlock ();
return FALSE;
}
if (req->source) {
stun_agent_forget_transaction (&req->priv->agent, req->id);
......@@ -370,7 +369,7 @@ priv_forget_send_request (gpointer pointer)
req->source = NULL;
}
g_static_rec_mutex_unlock (mutex);
agent_unlock ();
if (g_atomic_int_dec_and_test (&req->ref))
g_slice_free (SendRequest, req);
......@@ -658,7 +657,14 @@ priv_retransmissions_tick (gpointer pointer)
TurnPriv *priv = pointer;
gboolean ret;
g_static_rec_mutex_lock (&priv->nice->mutex);
agent_lock ();
if (g_source_is_destroyed (g_main_current_source ())) {
nice_debug ("Source was destroyed. "
"Avoided race condition in turn.c:priv_retransmissions_tick");
agent_unlock ();
return FALSE;
}
ret = priv_retransmissions_tick_unlocked (priv);
if (ret == FALSE) {
if (priv->tick_source != NULL) {
......@@ -667,7 +673,7 @@ priv_retransmissions_tick (gpointer pointer)
priv->tick_source = NULL;
}
}
g_static_rec_mutex_unlock (&priv->nice->mutex);
agent_unlock ();
return ret;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment