Commit 41961275 authored by Youness Alaoui's avatar Youness Alaoui

Do not unlock the mutex when emitting the signal because it might unlock...

Do not unlock the mutex when emitting the signal because it might unlock another thread which could cause a race condition.
To avoid a deadlock when a signal callback calls an API function that does a g_mutex_lock while the lock is already taken. Change the mutex into a recursive mutex
parent f07a470f
...@@ -91,7 +91,7 @@ struct _NiceAgent ...@@ -91,7 +91,7 @@ struct _NiceAgent
guint keepalive_timer_id; /**< id of keepalive timer */ guint keepalive_timer_id; /**< id of keepalive timer */
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) */
GMutex * mutex; /* Mutex used for thread-safe lib */ GStaticRecMutex mutex; /* Mutex used for thread-safe lib */
NiceCompatibility compatibility; /* property: Compatibility mode */ NiceCompatibility compatibility; /* property: Compatibility mode */
/* XXX: add pointer to internal data struct for ABI-safe extensions */ /* XXX: add pointer to internal data struct for ABI-safe extensions */
}; };
......
...@@ -401,7 +401,8 @@ nice_agent_init (NiceAgent *agent) ...@@ -401,7 +401,8 @@ 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);
agent->mutex = g_mutex_new ();
g_static_rec_mutex_init (&agent->mutex);
} }
...@@ -436,7 +437,7 @@ nice_agent_get_property ( ...@@ -436,7 +437,7 @@ nice_agent_get_property (
{ {
NiceAgent *agent = NICE_AGENT (object); NiceAgent *agent = NICE_AGENT (object);
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
switch (property_id) switch (property_id)
{ {
...@@ -489,7 +490,7 @@ nice_agent_get_property ( ...@@ -489,7 +490,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_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
} }
...@@ -502,7 +503,7 @@ nice_agent_set_property ( ...@@ -502,7 +503,7 @@ nice_agent_set_property (
{ {
NiceAgent *agent = NICE_AGENT (object); NiceAgent *agent = NICE_AGENT (object);
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
switch (property_id) switch (property_id)
{ {
...@@ -550,7 +551,7 @@ nice_agent_set_property ( ...@@ -550,7 +551,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_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
} }
...@@ -589,9 +590,7 @@ void agent_gathering_done (NiceAgent *agent) ...@@ -589,9 +590,7 @@ void agent_gathering_done (NiceAgent *agent)
void agent_signal_gathering_done (NiceAgent *agent) void agent_signal_gathering_done (NiceAgent *agent)
{ {
g_mutex_unlock (agent->mutex);
g_signal_emit (agent, signals[SIGNAL_CANDIDATE_GATHERING_DONE], 0); g_signal_emit (agent, signals[SIGNAL_CANDIDATE_GATHERING_DONE], 0);
g_mutex_lock (agent->mutex);
} }
void agent_signal_initial_binding_request_received (NiceAgent *agent, Stream *stream) void agent_signal_initial_binding_request_received (NiceAgent *agent, Stream *stream)
...@@ -614,11 +613,9 @@ void agent_signal_new_selected_pair (NiceAgent *agent, guint stream_id, guint co ...@@ -614,11 +613,9 @@ void agent_signal_new_selected_pair (NiceAgent *agent, guint stream_id, guint co
lf_copy = g_strdup (local_foundation); lf_copy = g_strdup (local_foundation);
rf_copy = g_strdup (remote_foundation); rf_copy = g_strdup (remote_foundation);
g_mutex_unlock (agent->mutex);
g_signal_emit (agent, signals[SIGNAL_NEW_SELECTED_PAIR], 0, g_signal_emit (agent, signals[SIGNAL_NEW_SELECTED_PAIR], 0,
stream_id, component_id, lf_copy, rf_copy); stream_id, component_id, lf_copy, rf_copy);
g_mutex_lock (agent->mutex);
g_free (lf_copy); g_free (lf_copy);
g_free (rf_copy); g_free (rf_copy);
...@@ -653,10 +650,8 @@ void agent_signal_component_state_change (NiceAgent *agent, guint stream_id, gui ...@@ -653,10 +650,8 @@ void agent_signal_component_state_change (NiceAgent *agent, guint stream_id, gui
component->state = state; component->state = state;
g_mutex_unlock (agent->mutex);
g_signal_emit (agent, signals[SIGNAL_COMPONENT_STATE_CHANGED], 0, g_signal_emit (agent, signals[SIGNAL_COMPONENT_STATE_CHANGED], 0,
stream_id, component_id, state); stream_id, component_id, state);
g_mutex_lock (agent->mutex);
} }
} }
...@@ -723,7 +718,7 @@ nice_agent_add_stream ( ...@@ -723,7 +718,7 @@ nice_agent_add_stream (
GSList *modified_list = NULL; GSList *modified_list = NULL;
guint ret = 0; guint ret = 0;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
if (!agent->local_addresses) { if (!agent->local_addresses) {
goto done; goto done;
...@@ -747,7 +742,7 @@ nice_agent_add_stream ( ...@@ -747,7 +742,7 @@ nice_agent_add_stream (
ret = stream->id; ret = stream->id;
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -767,7 +762,7 @@ nice_agent_gather_candidates ( ...@@ -767,7 +762,7 @@ nice_agent_gather_candidates (
GSList *i; GSList *i;
Stream *stream; Stream *stream;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (stream == NULL) { if (stream == NULL) {
...@@ -823,7 +818,7 @@ nice_agent_gather_candidates ( ...@@ -823,7 +818,7 @@ nice_agent_gather_candidates (
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
} }
static void priv_remove_keepalive_timer (NiceAgent *agent) static void priv_remove_keepalive_timer (NiceAgent *agent)
...@@ -849,7 +844,7 @@ nice_agent_remove_stream ( ...@@ -849,7 +844,7 @@ nice_agent_remove_stream (
Stream *stream; Stream *stream;
GSList *i; GSList *i;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (!stream) { if (!stream) {
...@@ -872,7 +867,7 @@ nice_agent_remove_stream ( ...@@ -872,7 +867,7 @@ nice_agent_remove_stream (
priv_remove_keepalive_timer (agent); priv_remove_keepalive_timer (agent);
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
} }
/** /**
...@@ -892,7 +887,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) ...@@ -892,7 +887,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
GSList *modified_list; GSList *modified_list;
gboolean ret = FALSE; gboolean ret = FALSE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
dup = nice_address_dup (addr); dup = nice_address_dup (addr);
nice_address_set_port (dup, 0); nice_address_set_port (dup, 0);
...@@ -905,7 +900,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) ...@@ -905,7 +900,7 @@ nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr)
} }
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1034,7 +1029,7 @@ nice_agent_set_remote_credentials ( ...@@ -1034,7 +1029,7 @@ nice_agent_set_remote_credentials (
Stream *stream; Stream *stream;
gboolean ret = FALSE; gboolean ret = FALSE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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 */
...@@ -1048,7 +1043,7 @@ nice_agent_set_remote_credentials ( ...@@ -1048,7 +1043,7 @@ nice_agent_set_remote_credentials (
} }
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1073,7 +1068,7 @@ nice_agent_get_local_credentials ( ...@@ -1073,7 +1068,7 @@ nice_agent_get_local_credentials (
Stream *stream; Stream *stream;
gboolean ret = TRUE; gboolean ret = TRUE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
stream = agent_find_stream (agent, stream_id); stream = agent_find_stream (agent, stream_id);
if (stream == NULL) { if (stream == NULL) {
...@@ -1090,7 +1085,7 @@ nice_agent_get_local_credentials ( ...@@ -1090,7 +1085,7 @@ nice_agent_get_local_credentials (
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1123,7 +1118,7 @@ nice_agent_add_remote_candidate ( ...@@ -1123,7 +1118,7 @@ nice_agent_add_remote_candidate (
/* XXX: to be deprecated */ /* XXX: to be deprecated */
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* XXX: should we allow use of this method without an /* XXX: should we allow use of this method without an
* initial call to nice_agent_set_remote_candidates() * initial call to nice_agent_set_remote_candidates()
...@@ -1146,7 +1141,7 @@ nice_agent_add_remote_candidate ( ...@@ -1146,7 +1141,7 @@ nice_agent_add_remote_candidate (
candidate, see below set_remote_candidates() */ candidate, see below set_remote_candidates() */
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1176,7 +1171,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo ...@@ -1176,7 +1171,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
if (agent->discovery_unsched_items > 0) if (agent->discovery_unsched_items > 0)
return -1; return -1;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
for (i = candidates; i && added >= 0; i = i->next) { for (i = candidates; i && added >= 0; i = i->next) {
NiceCandidate *d = (NiceCandidate*) i->data; NiceCandidate *d = (NiceCandidate*) i->data;
...@@ -1206,7 +1201,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo ...@@ -1206,7 +1201,7 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
g_debug ("Agent %p : Warning: unable to schedule any conn checks!", agent); g_debug ("Agent %p : Warning: unable to schedule any conn checks!", agent);
} }
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return added; return added;
} }
...@@ -1310,7 +1305,7 @@ nice_agent_recv ( ...@@ -1310,7 +1305,7 @@ nice_agent_recv (
Component *component; Component *component;
guint ret = 0; guint ret = 0;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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;
} }
...@@ -1361,7 +1356,7 @@ nice_agent_recv ( ...@@ -1361,7 +1356,7 @@ nice_agent_recv (
* *
* g_assert_not_reached (); */ * g_assert_not_reached (); */
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1379,7 +1374,7 @@ nice_agent_recv_sock ( ...@@ -1379,7 +1374,7 @@ nice_agent_recv_sock (
Component *component; Component *component;
guint ret = 0; guint ret = 0;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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;
} }
...@@ -1391,7 +1386,7 @@ nice_agent_recv_sock ( ...@@ -1391,7 +1386,7 @@ nice_agent_recv_sock (
socket, buf_len, buf); socket, buf_len, buf);
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1422,7 +1417,7 @@ nice_agent_poll_read ( ...@@ -1422,7 +1417,7 @@ nice_agent_poll_read (
GSList *i; GSList *i;
guint j; guint j;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
FD_ZERO (&fds); FD_ZERO (&fds);
...@@ -1507,7 +1502,7 @@ nice_agent_poll_read ( ...@@ -1507,7 +1502,7 @@ nice_agent_poll_read (
} }
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1534,7 +1529,7 @@ nice_agent_send ( ...@@ -1534,7 +1529,7 @@ nice_agent_send (
Component *component; Component *component;
guint ret = -1; guint ret = -1;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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;
...@@ -1564,7 +1559,7 @@ nice_agent_send ( ...@@ -1564,7 +1559,7 @@ nice_agent_send (
} }
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1589,7 +1584,7 @@ nice_agent_get_local_candidates ( ...@@ -1589,7 +1584,7 @@ nice_agent_get_local_candidates (
GSList * ret = NULL; GSList * ret = NULL;
GSList * item = NULL; GSList * item = NULL;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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;
...@@ -1599,7 +1594,7 @@ nice_agent_get_local_candidates ( ...@@ -1599,7 +1594,7 @@ nice_agent_get_local_candidates (
ret = g_slist_append (ret, nice_candidate_copy (item->data)); ret = g_slist_append (ret, nice_candidate_copy (item->data));
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1626,7 +1621,7 @@ nice_agent_get_remote_candidates ( ...@@ -1626,7 +1621,7 @@ nice_agent_get_remote_candidates (
Component *component; Component *component;
GSList *ret = NULL, *item = NULL; GSList *ret = NULL, *item = NULL;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
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;
...@@ -1636,7 +1631,7 @@ nice_agent_get_remote_candidates ( ...@@ -1636,7 +1631,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_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1658,7 +1653,7 @@ nice_agent_restart ( ...@@ -1658,7 +1653,7 @@ nice_agent_restart (
GSList *i; GSList *i;
gboolean res = TRUE; gboolean res = TRUE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* step: clean up all connectivity checks */ /* step: clean up all connectivity checks */
conn_check_free (agent); conn_check_free (agent);
...@@ -1674,7 +1669,7 @@ nice_agent_restart ( ...@@ -1674,7 +1669,7 @@ nice_agent_restart (
res = stream_restart (stream, agent->rng); res = stream_restart (stream, agent->rng);
} }
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return res; return res;
} }
...@@ -1724,7 +1719,7 @@ nice_agent_dispose (GObject *object) ...@@ -1724,7 +1719,7 @@ 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_mutex_free (agent->mutex); g_static_rec_mutex_free (&agent->mutex);
} }
...@@ -1781,7 +1776,7 @@ nice_agent_g_source_cb ( ...@@ -1781,7 +1776,7 @@ nice_agent_g_source_cb (
gchar buf[MAX_BUFFER_SIZE]; gchar buf[MAX_BUFFER_SIZE];
guint len; guint len;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* note: dear compiler, these are for you: */ /* note: dear compiler, these are for you: */
(void)source; (void)source;
...@@ -1793,7 +1788,7 @@ nice_agent_g_source_cb ( ...@@ -1793,7 +1788,7 @@ nice_agent_g_source_cb (
component->g_source_io_cb (agent, stream->id, component->id, component->g_source_io_cb (agent, stream->id, component->id,
len, buf, component->data); len, buf, component->data);
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return TRUE; return TRUE;
} }
...@@ -1877,7 +1872,7 @@ nice_agent_attach_recv ( ...@@ -1877,7 +1872,7 @@ nice_agent_attach_recv (
Stream *stream = NULL; Stream *stream = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* attach candidates */ /* attach candidates */
...@@ -1906,7 +1901,7 @@ nice_agent_attach_recv ( ...@@ -1906,7 +1901,7 @@ nice_agent_attach_recv (
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -1930,7 +1925,7 @@ nice_agent_set_selected_pair ( ...@@ -1930,7 +1925,7 @@ nice_agent_set_selected_pair (
CandidatePair pair; CandidatePair pair;
gboolean ret = FALSE; gboolean ret = FALSE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* 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)) {
...@@ -1954,7 +1949,7 @@ nice_agent_set_selected_pair ( ...@@ -1954,7 +1949,7 @@ nice_agent_set_selected_pair (
ret = TRUE; ret = TRUE;
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
......
...@@ -389,9 +389,9 @@ static gboolean priv_conn_check_tick (gpointer pointer) ...@@ -389,9 +389,9 @@ static gboolean priv_conn_check_tick (gpointer pointer)
NiceAgent *agent = pointer; NiceAgent *agent = pointer;
gboolean ret; gboolean ret;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
ret = priv_conn_check_tick_unlocked (pointer); ret = priv_conn_check_tick_unlocked (pointer);
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
...@@ -411,7 +411,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer) ...@@ -411,7 +411,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer)
int errors = 0; int errors = 0;
gboolean ret = FALSE; gboolean ret = FALSE;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
/* case 1: session established and media flowing /* case 1: session established and media flowing
* (ref ICE sect 10 "Keepalives" ID-19) */ * (ref ICE sect 10 "Keepalives" ID-19) */
...@@ -464,7 +464,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer) ...@@ -464,7 +464,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer)
ret = TRUE; ret = TRUE;
done: done:
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
return ret; return ret;
} }
......
...@@ -576,9 +576,9 @@ static gboolean priv_discovery_tick (gpointer pointer) ...@@ -576,9 +576,9 @@ static gboolean priv_discovery_tick (gpointer pointer)
NiceAgent *agent = pointer; NiceAgent *agent = pointer;
gboolean ret; gboolean ret;
g_mutex_lock (agent->mutex); g_static_rec_mutex_lock (&agent->mutex);
ret = priv_discovery_tick_unlocked (pointer); ret = priv_discovery_tick_unlocked (pointer);
g_mutex_unlock (agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
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