summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2020-12-17 12:06:38 +0100
committerOlivier CrĂȘte <olivier.crete@ocrete.ca>2021-04-20 19:37:08 +0000
commite7b0b78650d5678d38fcede0b4feffca57c067c5 (patch)
tree12792d57ecb83ebd8a9f871d69258719f6a12be7
parent3e3a2b62ea811b94ed930c48ad9851fa60b04ba6 (diff)
downloadlibnice-e7b0b78650d5678d38fcede0b4feffca57c067c5.tar.gz
discovery: fix asynchronous agent refreshes pruning
Asynchronous refreshes pruning may occur when the agent async close function is called, but also when a stream is closed. A flag 'discarding' is used in the CandidateRefresh object to determine if a refresh is already on the way to be asynchronously freed. A refresh definitely freed is removed from agent refresh_list. When the agent async close function is called, it is passed a user callback that will be invoked when all refreshes have been freed. This is not exactly how things work currently, because right now, the callback function is also invoked when all CandidateRefresh objects have the discarding flag set, with the test 'data->items_to_free==0'. In that case, clearly not all refreshes have been freed, as some are still there in the refresh_list with the discarding flag set. This is probably not what the user expects from the function nice_agent_close_async(), where the callback is supposed to be invoked after all refreshes have been freed: and including those asynchronously pruned by nice_prune_stream_async(). This patch adds a supplementary timeout when closing the agent async, that waits until the agent refresh list becomes empty.
-rw-r--r--agent/agent.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/agent/agent.c b/agent/agent.c
index 8d2349a..e6132eb 100644
--- a/agent/agent.c
+++ b/agent/agent.c
@@ -7127,6 +7127,15 @@ on_agent_refreshes_pruned (NiceAgent *agent, gpointer user_data)
{
GTask *task = user_data;
+ if (agent->refresh_list) {
+ GSource *timeout_source = NULL;
+ agent_timeout_add_with_context (agent, &timeout_source,
+ "Async refresh prune", agent->stun_initial_timeout,
+ on_agent_refreshes_pruned, user_data);
+ g_source_unref (timeout_source);
+ return G_SOURCE_REMOVE;
+ }
+
/* This is called from a timeout cb with agent lock held */
agent_unlock (agent);