<p>Joshua Colp has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8926">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">stream: Make the topology a reference counted object.<br><br>The stream topology has no lock of its own resulting in<br>another lock protecting it in some way (for example the<br>channel lock). If multiple channels are being juggled at<br>the same time this can be problematic. This change makes<br>the topology a reference counted object instead which<br>guarantees it will remain valid even without the channel<br>lock being held.<br><br>Change-Id: I4f4d3dd856a033ed55fe218c3a4fab364afedb03<br>---<br>M bridges/bridge_softmix.c<br>M include/asterisk/stream.h<br>M main/stream.c<br>3 files changed, 17 insertions(+), 19 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/26/8926/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c<br>index f0a3fb4..da84ee0 100644<br>--- a/bridges/bridge_softmix.c<br>+++ b/bridges/bridge_softmix.c<br>@@ -2110,15 +2110,7 @@<br> ast_bridge_channel_lock(participant);<br> ast_channel_lock(participant->chan);<br> <br>- topology = ast_channel_get_stream_topology(participant->chan);<br>- if (topology) {<br>- /*<br>- * Sigh. We have to clone to avoid deadlock in<br>- * map_source_to_destinations() because topology<br>- * is not an ao2 object.<br>- */<br>- topology = ast_stream_topology_clone(topology);<br>- }<br>+ topology = ao2_bump(ast_channel_get_stream_topology(participant->chan));<br> if (!topology) {<br> /* Oh, my, we are in trouble. */<br> ast_channel_unlock(participant->chan);<br>diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h<br>index bbde73d..a53ec74 100644<br>--- a/include/asterisk/stream.h<br>+++ b/include/asterisk/stream.h<br>@@ -273,6 +273,8 @@<br> * \retval NULL failure<br> *<br> * \since 15<br>+ *<br>+ * \note This returns an ao2 refcounted object<br> */<br> struct ast_stream_topology *ast_stream_topology_alloc(void);<br> <br>@@ -285,6 +287,8 @@<br> * \retval NULL failure<br> *<br> * \since 15<br>+ *<br>+ * \note This returns an ao2 refcounted object<br> */<br> struct ast_stream_topology *ast_stream_topology_clone(<br> const struct ast_stream_topology *topology);<br>@@ -304,7 +308,7 @@<br> const struct ast_stream_topology *right);<br> <br> /*!<br>- * \brief Destroy a stream topology<br>+ * \brief Unreference and destroy a stream topology<br> *<br> * \param topology The topology of streams<br> *<br>diff --git a/main/stream.c b/main/stream.c<br>index 8597485..6ce55eb 100644<br>--- a/main/stream.c<br>+++ b/main/stream.c<br>@@ -246,18 +246,26 @@<br> return stream->position;<br> }<br> <br>+static void stream_topology_destroy(void *data)<br>+{<br>+ struct ast_stream_topology *topology = data;<br>+<br>+ AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free);<br>+ AST_VECTOR_FREE(&topology->streams);<br>+}<br>+<br> #define TOPOLOGY_INITIAL_STREAM_COUNT 2<br> struct ast_stream_topology *ast_stream_topology_alloc(void)<br> {<br> struct ast_stream_topology *topology;<br> <br>- topology = ast_calloc(1, sizeof(*topology));<br>+ topology = ao2_alloc_options(sizeof(*topology), stream_topology_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);<br> if (!topology) {<br> return NULL;<br> }<br> <br> if (AST_VECTOR_INIT(&topology->streams, TOPOLOGY_INITIAL_STREAM_COUNT)) {<br>- ast_free(topology);<br>+ ao2_ref(topology, -1);<br> topology = NULL;<br> }<br> <br>@@ -342,13 +350,7 @@<br> <br> void ast_stream_topology_free(struct ast_stream_topology *topology)<br> {<br>- if (!topology) {<br>- return;<br>- }<br>-<br>- AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free);<br>- AST_VECTOR_FREE(&topology->streams);<br>- ast_free(topology);<br>+ ao2_cleanup(topology);<br> }<br> <br> int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8926">change 8926</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8926"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I4f4d3dd856a033ed55fe218c3a4fab364afedb03 </div>
<div style="display:none"> Gerrit-Change-Number: 8926 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@digium.com> </div>