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,
......
...@@ -115,6 +115,8 @@ enum ...@@ -115,6 +115,8 @@ enum
static guint signals[N_SIGNALS]; static guint signals[N_SIGNALS];
static GStaticRecMutex agent_mutex = G_STATIC_REC_MUTEX_INIT; /* Mutex used for thread-safe lib */
static gboolean priv_attach_stream_component (NiceAgent *agent, static gboolean priv_attach_stream_component (NiceAgent *agent,
Stream *stream, Stream *stream,
Component *component); Component *component);
...@@ -122,6 +124,19 @@ static void priv_detach_stream_component (Stream *stream, Component *component); ...@@ -122,6 +124,19 @@ static void priv_detach_stream_component (Stream *stream, Component *component);
static void priv_free_upnp (NiceAgent *agent); static void priv_free_upnp (NiceAgent *agent);
void agent_lock (void)
{
g_static_rec_mutex_lock (&agent_mutex);
}
void agent_unlock (void)
{
g_static_rec_mutex_unlock (&agent_mutex);
}
StunUsageIceCompatibility StunUsageIceCompatibility
agent_to_ice_compatibility (NiceAgent *agent) agent_to_ice_compatibility (NiceAgent *agent)
{ {
...@@ -548,8 +563,6 @@ nice_agent_init (NiceAgent *agent) ...@@ -548,8 +563,6 @@ nice_agent_init (NiceAgent *agent)
agent->rng = nice_rng_new (); agent->rng = nice_rng_new ();
priv_generate_tie_breaker (agent); priv_generate_tie_breaker (agent);
g_static_rec_mutex_init (&agent->mutex);
} }
...@@ -574,7 +587,7 @@ nice_agent_get_property ( ...@@ -574,7 +587,7 @@ nice_agent_get_property (
{ {
NiceAgent *agent = NICE_AGENT (object); NiceAgent *agent = NICE_AGENT (object);
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
switch (property_id) switch (property_id)
{ {
...@@ -645,7 +658,7 @@ nice_agent_get_property ( ...@@ -645,7 +658,7 @@ nice_agent_get_property (
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
...@@ -658,7 +671,7 @@ nice_agent_set_property ( ...@@ -658,7 +671,7 @@ nice_agent_set_property (
{ {
NiceAgent *agent = NICE_AGENT (object); NiceAgent *agent = NICE_AGENT (object);
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
switch (property_id) switch (property_id)
{ {
...@@ -749,7 +762,7 @@ nice_agent_set_property ( ...@@ -749,7 +762,7 @@ nice_agent_set_property (
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
...@@ -1061,7 +1074,7 @@ nice_agent_add_stream ( ...@@ -1061,7 +1074,7 @@ nice_agent_add_stream (
GSList *modified_list = NULL; GSList *modified_list = NULL;
guint ret = 0; guint ret = 0;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = stream_new (n_components); stream = stream_new (n_components);
if (stream) { if (stream) {
...@@ -1080,7 +1093,7 @@ nice_agent_add_stream ( ...@@ -1080,7 +1093,7 @@ nice_agent_add_stream (
ret = stream->id; ret = stream->id;
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1101,7 +1114,7 @@ nice_agent_set_relay_info(NiceAgent *agent, ...@@ -1101,7 +1114,7 @@ nice_agent_set_relay_info(NiceAgent *agent,
g_return_val_if_fail (password, FALSE); g_return_val_if_fail (password, FALSE);
g_return_val_if_fail (type <= NICE_PROXY_TYPE_LAST, FALSE); g_return_val_if_fail (type <= NICE_PROXY_TYPE_LAST, FALSE);
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (agent_find_component (agent, stream_id, component_id, NULL, &component)) { if (agent_find_component (agent, stream_id, component_id, NULL, &component)) {
TurnServer *turn = g_slice_new0 (TurnServer); TurnServer *turn = g_slice_new0 (TurnServer);
...@@ -1111,7 +1124,7 @@ nice_agent_set_relay_info(NiceAgent *agent, ...@@ -1111,7 +1124,7 @@ nice_agent_set_relay_info(NiceAgent *agent,
nice_address_set_port (&turn->server, server_port); nice_address_set_port (&turn->server, server_port);
} else { } else {
g_slice_free (TurnServer, turn); g_slice_free (TurnServer, turn);
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return FALSE; return FALSE;
} }
...@@ -1126,7 +1139,7 @@ nice_agent_set_relay_info(NiceAgent *agent, ...@@ -1126,7 +1139,7 @@ nice_agent_set_relay_info(NiceAgent *agent,
component->turn_servers = g_list_append (component->turn_servers, turn); component->turn_servers = g_list_append (component->turn_servers, turn);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return TRUE; return TRUE;
} }
...@@ -1137,7 +1150,12 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data) ...@@ -1137,7 +1150,12 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data)
NiceAgent *agent = (NiceAgent*)user_data; NiceAgent *agent = (NiceAgent*)user_data;
GSList *i; GSList *i;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
agent_unlock ();
return FALSE;
}
nice_debug ("Agent %p : UPnP port mapping timed out", agent); nice_debug ("Agent %p : UPnP port mapping timed out", agent);
...@@ -1156,7 +1174,7 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data) ...@@ -1156,7 +1174,7 @@ static gboolean priv_upnp_timeout_cb (gpointer user_data)
agent_gathering_done (agent); agent_gathering_done (agent);
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return FALSE; return FALSE;
} }
...@@ -1170,7 +1188,7 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, ...@@ -1170,7 +1188,7 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto,
GSList *i, *j, *k; GSList *i, *j, *k;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
nice_debug ("Agent %p : Sucessfully mapped %s:%d to %s:%d", agent, local_ip, nice_debug ("Agent %p : Sucessfully mapped %s:%d to %s:%d", agent, local_ip,
local_port, external_ip, external_port); local_port, external_ip, external_port);
...@@ -1222,7 +1240,7 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, ...@@ -1222,7 +1240,7 @@ static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto,
agent_gathering_done (agent); agent_gathering_done (agent);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error, static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error,
...@@ -1233,7 +1251,7 @@ static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error, ...@@ -1233,7 +1251,7 @@ static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error,
NiceAddress localaddr; NiceAddress localaddr;
GSList *i; GSList *i;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
nice_debug ("Agent %p : Error mapping %s:%d to %d (%d) : %s", agent, local_ip, nice_debug ("Agent %p : Error mapping %s:%d to %d (%d) : %s", agent, local_ip,
local_port, external_port, error->domain, error->message); local_port, external_port, error->domain, error->message);
...@@ -1259,7 +1277,7 @@ static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error, ...@@ -1259,7 +1277,7 @@ static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error,
} }
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
#endif #endif
...@@ -1273,7 +1291,7 @@ nice_agent_gather_candidates ( ...@@ -1273,7 +1291,7 @@ nice_agent_gather_candidates (
GSList *i; GSList *i;
Stream *stream; Stream *stream;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (stream == NULL) { if (stream == NULL) {
...@@ -1415,7 +1433,7 @@ nice_agent_gather_candidates ( ...@@ -1415,7 +1433,7 @@ nice_agent_gather_candidates (
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
static void priv_free_upnp (NiceAgent *agent) static void priv_free_upnp (NiceAgent *agent)
...@@ -1462,7 +1480,7 @@ nice_agent_remove_stream ( ...@@ -1462,7 +1480,7 @@ nice_agent_remove_stream (
Stream *stream; Stream *stream;
GSList *i; GSList *i;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (!stream) { if (!stream) {
...@@ -1486,7 +1504,7 @@ nice_agent_remove_stream ( ...@@ -1486,7 +1504,7 @@ nice_agent_remove_stream (
priv_remove_keepalive_timer (agent); priv_remove_keepalive_timer (agent);
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
} }
NICEAPI_EXPORT gboolean NICEAPI_EXPORT gboolean
...@@ -1496,7 +1514,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) ...@@ -1496,7 +1514,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
GSList *modified_list; GSList *modified_list;
gboolean ret = FALSE; gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
dup = nice_address_dup (addr); dup = nice_address_dup (addr);
nice_address_set_port (dup, 0); nice_address_set_port (dup, 0);
...@@ -1509,7 +1527,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) ...@@ -1509,7 +1527,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
} }
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1628,7 +1646,7 @@ nice_agent_set_remote_credentials ( ...@@ -1628,7 +1646,7 @@ nice_agent_set_remote_credentials (
Stream *stream; Stream *stream;
gboolean ret = FALSE; gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
/* note: oddly enough, ufrag and pwd can be empty strings */ /* note: oddly enough, ufrag and pwd can be empty strings */
...@@ -1642,7 +1660,7 @@ nice_agent_set_remote_credentials ( ...@@ -1642,7 +1660,7 @@ nice_agent_set_remote_credentials (
} }
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1656,7 +1674,7 @@ nice_agent_get_local_credentials ( ...@@ -1656,7 +1674,7 @@ nice_agent_get_local_credentials (
Stream *stream; Stream *stream;
gboolean ret = TRUE; gboolean ret = TRUE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (stream == NULL) { if (stream == NULL) {
...@@ -1673,7 +1691,7 @@ nice_agent_get_local_credentials ( ...@@ -1673,7 +1691,7 @@ nice_agent_get_local_credentials (
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1686,7 +1704,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo ...@@ -1686,7 +1704,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
nice_debug ("Agent %p: set_remote_candidates %d %d", agent, stream_id, component_id); nice_debug ("Agent %p: set_remote_candidates %d %d", agent, stream_id, component_id);
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (stream == NULL) { if (stream == NULL) {
...@@ -1730,7 +1748,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo ...@@ -1730,7 +1748,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
} }
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return added; return added;
} }
...@@ -1820,7 +1838,7 @@ nice_agent_send ( ...@@ -1820,7 +1838,7 @@ nice_agent_send (
Component *component; Component *component;
guint ret = -1; guint ret = -1;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) {
goto done; goto done;
...@@ -1849,7 +1867,7 @@ nice_agent_send ( ...@@ -1849,7 +1867,7 @@ nice_agent_send (
} }
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1864,17 +1882,16 @@ nice_agent_get_local_candidates ( ...@@ -1864,17 +1882,16 @@ nice_agent_get_local_candidates (
GSList * ret = NULL; GSList * ret = NULL;
GSList * item = NULL; GSList * item = NULL;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) {
{ goto done;
goto done; }
}
for (item = component->local_candidates; item; item = item->next) for (item = component->local_candidates; item; item = item->next)
ret = g_slist_append (ret, nice_candidate_copy (item->data)); ret = g_slist_append (ret, nice_candidate_copy (item->data));
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1888,7 +1905,7 @@ nice_agent_get_remote_candidates ( ...@@ -1888,7 +1905,7 @@ nice_agent_get_remote_candidates (
Component *component; Component *component;
GSList *ret = NULL, *item = NULL; GSList *ret = NULL, *item = NULL;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) if (!agent_find_component (agent, stream_id, component_id, NULL, &component))
{ {
goto done; goto done;
...@@ -1898,7 +1915,7 @@ nice_agent_get_remote_candidates ( ...@@ -1898,7 +1915,7 @@ nice_agent_get_remote_candidates (
ret = g_slist_append (ret, nice_candidate_copy (item->data)); ret = g_slist_append (ret, nice_candidate_copy (item->data));
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -1910,7 +1927,7 @@ nice_agent_restart ( ...@@ -1910,7 +1927,7 @@ nice_agent_restart (
GSList *i; GSList *i;
gboolean res = TRUE; gboolean res = TRUE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
/* step: clean up all connectivity checks */ /* step: clean up all connectivity checks */
conn_check_free (agent); conn_check_free (agent);
...@@ -1926,7 +1943,7 @@ nice_agent_restart ( ...@@ -1926,7 +1943,7 @@ nice_agent_restart (
res = stream_restart (stream, agent->rng); res = stream_restart (stream, agent->rng);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return res; return res;
} }
...@@ -1979,7 +1996,6 @@ nice_agent_dispose (GObject *object) ...@@ -1979,7 +1996,6 @@ nice_agent_dispose (GObject *object)
if (G_OBJECT_CLASS (nice_agent_parent_class)->dispose) if (G_OBJECT_CLASS (nice_agent_parent_class)->dispose)
G_OBJECT_CLASS (nice_agent_parent_class)->dispose (object); G_OBJECT_CLASS (nice_agent_parent_class)->dispose (object);
g_static_rec_mutex_free (&agent->mutex);
} }
...@@ -2043,7 +2059,12 @@ nice_agent_g_source_cb ( ...@@ -2043,7 +2059,12 @@ nice_agent_g_source_cb (
gchar buf[MAX_BUFFER_SIZE]; gchar buf[MAX_BUFFER_SIZE];
gint len; gint len;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) {
agent_unlock ();
return FALSE;
}
/* note: dear compiler, these are for you: */ /* note: dear compiler, these are for you: */
(void)io; (void)io;
...@@ -2063,9 +2084,13 @@ nice_agent_g_source_cb ( ...@@ -2063,9 +2084,13 @@ nice_agent_g_source_cb (
* take care of every path where the socket might still be used.. */ * take care of every path where the socket might still be used.. */
nice_debug ("Agent %p: unable to recv from socket %p. Detaching", agent, nice_debug ("Agent %p: unable to recv from socket %p. Detaching", agent,
ctx->socket); ctx->socket);
} }
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
done:
return TRUE; return TRUE;
} }
...@@ -2150,7 +2175,7 @@ nice_agent_attach_recv ( ...@@ -2150,7 +2175,7 @@ nice_agent_attach_recv (
Stream *stream = NULL; Stream *stream = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
/* attach candidates */ /* attach candidates */
...@@ -2179,7 +2204,7 @@ nice_agent_attach_recv ( ...@@ -2179,7 +2204,7 @@ nice_agent_attach_recv (
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -2196,7 +2221,7 @@ nice_agent_set_selected_pair ( ...@@ -2196,7 +2221,7 @@ nice_agent_set_selected_pair (
CandidatePair pair; CandidatePair pair;
gboolean ret = FALSE; gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
/* step: check that params specify an existing pair */ /* step: check that params specify an existing pair */
if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) {
...@@ -2220,7 +2245,7 @@ nice_agent_set_selected_pair ( ...@@ -2220,7 +2245,7 @@ nice_agent_set_selected_pair (
ret = TRUE; ret = TRUE;
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -2254,7 +2279,7 @@ nice_agent_set_selected_remote_candidate ( ...@@ -2254,7 +2279,7 @@ nice_agent_set_selected_remote_candidate (
NiceCandidate *lcandidate = NULL; NiceCandidate *lcandidate = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
g_static_rec_mutex_lock (&agent->mutex); agent_lock();
/* step: check if the component exists*/ /* step: check if the component exists*/
if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) {
...@@ -2281,6 +2306,6 @@ nice_agent_set_selected_remote_candidate ( ...@@ -2281,6 +2306,6 @@ nice_agent_set_selected_remote_candidate (
ret = TRUE; ret = TRUE;
done: done:
g_static_rec_mutex_unlock (&agent->mutex); agent_unlock();
return ret; return ret;
} }
...@@ -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