Commit ca0f5c6d authored by Olivier Crête's avatar Olivier Crête

agent: Delay signal emission after the lock has been released

This way, there can be no annoying re-entrancy in our code.
parent 0fc36cb2
...@@ -158,6 +158,8 @@ struct _NiceAgent ...@@ -158,6 +158,8 @@ struct _NiceAgent
#endif #endif
gchar *software_attribute; /* SOFTWARE attribute */ gchar *software_attribute; /* SOFTWARE attribute */
gboolean reliable; /* property: reliable */ gboolean reliable; /* property: reliable */
GQueue pending_signals;
/* XXX: add pointer to internal data struct for ABI-safe extensions */ /* XXX: add pointer to internal data struct for ABI-safe extensions */
}; };
...@@ -176,6 +178,7 @@ void agent_signal_gathering_done (NiceAgent *agent); ...@@ -176,6 +178,7 @@ void agent_signal_gathering_done (NiceAgent *agent);
void agent_lock (void); void agent_lock (void);
void agent_unlock (void); void agent_unlock (void);
void agent_unlock_and_emit (NiceAgent *agent);
void agent_signal_new_selected_pair ( void agent_signal_new_selected_pair (
NiceAgent *agent, NiceAgent *agent,
......
This diff is collapsed.
...@@ -752,7 +752,7 @@ component_emit_io_callback (Component *component, ...@@ -752,7 +752,7 @@ component_emit_io_callback (Component *component,
* handler. */ * handler. */
if (g_main_context_is_owner (component->ctx)) { if (g_main_context_is_owner (component->ctx)) {
/* Thread owns the main context, so invoke the callback directly. */ /* Thread owns the main context, so invoke the callback directly. */
agent_unlock (); agent_unlock_and_emit (agent);
io_callback (agent, stream_id, io_callback (agent, stream_id,
component_id, buf_len, (gchar *) buf, io_user_data); component_id, buf_len, (gchar *) buf, io_user_data);
agent_lock (); agent_lock ();
...@@ -907,7 +907,7 @@ component_source_prepare (GSource *source, gint *timeout_) ...@@ -907,7 +907,7 @@ component_source_prepare (GSource *source, gint *timeout_)
done: done:
agent_unlock (); agent_unlock_and_emit (agent);
/* We can’t be sure if the ComponentSource itself needs to be dispatched until /* We can’t be sure if the ComponentSource itself needs to be dispatched until
* poll() is called on all the child sources. */ * poll() is called on all the child sources. */
......
...@@ -388,10 +388,9 @@ static gboolean priv_conn_check_tick_stream (Stream *stream, NiceAgent *agent, G ...@@ -388,10 +388,9 @@ static gboolean priv_conn_check_tick_stream (Stream *stream, NiceAgent *agent, G
* *
* @return will return FALSE when no more pending timers. * @return will return FALSE when no more pending timers.
*/ */
static gboolean priv_conn_check_tick_unlocked (gpointer pointer) static gboolean priv_conn_check_tick_unlocked (NiceAgent *agent)
{ {
CandidateCheckPair *pair = NULL; CandidateCheckPair *pair = NULL;
NiceAgent *agent = pointer;
gboolean keep_timer_going = FALSE; gboolean keep_timer_going = FALSE;
GSList *i, *j; GSList *i, *j;
GTimeVal now; GTimeVal now;
...@@ -454,6 +453,7 @@ static gboolean priv_conn_check_tick_unlocked (gpointer pointer) ...@@ -454,6 +453,7 @@ 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)
{ {
gboolean ret; gboolean ret;
NiceAgent *agent = pointer;
agent_lock(); agent_lock();
if (g_source_is_destroyed (g_main_current_source ())) { if (g_source_is_destroyed (g_main_current_source ())) {
...@@ -462,8 +462,9 @@ static gboolean priv_conn_check_tick (gpointer pointer) ...@@ -462,8 +462,9 @@ static gboolean priv_conn_check_tick (gpointer pointer)
agent_unlock (); agent_unlock ();
return FALSE; return FALSE;
} }
ret = priv_conn_check_tick_unlocked (pointer);
agent_unlock(); ret = priv_conn_check_tick_unlocked (agent);
agent_unlock_and_emit (agent);
return ret; return ret;
} }
...@@ -539,7 +540,7 @@ static gboolean priv_conn_keepalive_retransmissions_tick (gpointer pointer) ...@@ -539,7 +540,7 @@ static gboolean priv_conn_keepalive_retransmissions_tick (gpointer pointer)
} }
agent_unlock (); agent_unlock_and_emit (pair->keepalive.agent);
return FALSE; return FALSE;
} }
...@@ -723,7 +724,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer) ...@@ -723,7 +724,7 @@ static gboolean priv_conn_keepalive_tick (gpointer pointer)
agent->keepalive_timer_source = NULL; agent->keepalive_timer_source = NULL;
} }
} }
agent_unlock(); agent_unlock_and_emit (agent);
return ret; return ret;
} }
...@@ -782,7 +783,7 @@ static gboolean priv_turn_allocate_refresh_retransmissions_tick (gpointer pointe ...@@ -782,7 +783,7 @@ static gboolean priv_turn_allocate_refresh_retransmissions_tick (gpointer pointe
} }
agent_unlock (); agent_unlock_and_emit (cand->agent);
return FALSE; return FALSE;
} }
...@@ -867,7 +868,7 @@ static gboolean priv_turn_allocate_refresh_tick (gpointer pointer) ...@@ -867,7 +868,7 @@ static gboolean priv_turn_allocate_refresh_tick (gpointer pointer)
} }
priv_turn_allocate_refresh_tick_unlocked (cand); priv_turn_allocate_refresh_tick_unlocked (cand);
agent_unlock (); agent_unlock_and_emit (cand->agent);
return FALSE; return FALSE;
} }
...@@ -887,7 +888,7 @@ gboolean conn_check_schedule_next (NiceAgent *agent) ...@@ -887,7 +888,7 @@ gboolean conn_check_schedule_next (NiceAgent *agent)
nice_debug ("Agent %p : WARN: starting conn checks before local candidate gathering is finished.", agent); nice_debug ("Agent %p : WARN: starting conn checks before local candidate gathering is finished.", agent);
/* step: call once imediately */ /* step: call once imediately */
res = priv_conn_check_tick_unlocked ((gpointer) agent); res = priv_conn_check_tick_unlocked (agent);
nice_debug ("Agent %p : priv_conn_check_tick_unlocked returned %d", agent, res); nice_debug ("Agent %p : priv_conn_check_tick_unlocked returned %d", agent, res);
/* step: schedule timer if not running yet */ /* step: schedule timer if not running yet */
......
...@@ -1029,7 +1029,7 @@ static gboolean priv_discovery_tick (gpointer pointer) ...@@ -1029,7 +1029,7 @@ static gboolean priv_discovery_tick (gpointer pointer)
agent->discovery_timer_source = NULL; agent->discovery_timer_source = NULL;
} }
} }
agent_unlock(); agent_unlock_and_emit (agent);
return ret; return ret;
} }
...@@ -1045,7 +1045,7 @@ void discovery_schedule (NiceAgent *agent) ...@@ -1045,7 +1045,7 @@ void discovery_schedule (NiceAgent *agent)
g_assert (agent->discovery_list != NULL); g_assert (agent->discovery_list != NULL);
if (agent->discovery_unsched_items > 0) { if (agent->discovery_unsched_items > 0) {
if (agent->discovery_timer_source == NULL) { if (agent->discovery_timer_source == NULL) {
/* step: run first iteration immediately */ /* step: run first iteration immediately */
gboolean res = priv_discovery_tick_unlocked (agent); gboolean res = priv_discovery_tick_unlocked (agent);
......
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