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