diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-03-04 13:48:03 +0000 |
---|---|---|
committer | Olivier Crête <olivier.crete@collabora.com> | 2014-03-04 15:47:25 -0500 |
commit | e62d47d6b4e955f21c15c95cb78fdd823853dd80 (patch) | |
tree | 5f25028fd856ca0b4724ca9f8420ad3dbf03a25b /agent | |
parent | d3a640c20cbf5d1f7385bec15739c2ea880326ad (diff) | |
download | libnice-e62d47d6b4e955f21c15c95cb78fdd823853dd80.tar.gz |
agent: Fix a potential re-entrancy situation
If we emit signals from component_io_cb() in the middle of a read, it’s
possible that one of those signals will be picked up by the client to
perform another read. A likely candidate (and what was triggering the
re-entrancy here) would be component-state-changed. Since signals are
emitted synchronously, the second read would being inside the first, and
trigger the anti-re-entrancy assertion.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/agent.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/agent/agent.c b/agent/agent.c index 689a2f6..3c22959 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -3876,8 +3876,14 @@ component_io_cb (GSocket *socket, GIOCondition condition, gpointer user_data) } done: - - agent_unlock_and_emit (agent); + /* If we’re in the middle of a read, don’t emit any signals, or we could cause + * re-entrancy by (e.g.) emitting component-state-changed and having the + * client perform a read. */ + if (component->n_recv_messages == 0 && component->recv_messages == NULL) { + agent_unlock_and_emit (agent); + } else { + agent_unlock (); + } g_object_unref (agent); |