<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8926">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Matthew Fredrickson: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><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;">diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c<br>index 23dc548..46b27f1 100644<br>--- a/bridges/bridge_softmix.c<br>+++ b/bridges/bridge_softmix.c<br>@@ -2159,15 +2159,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 99998c7..30001e0 100644<br>--- a/include/asterisk/stream.h<br>+++ b/include/asterisk/stream.h<br>@@ -274,6 +274,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>@@ -286,6 +288,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>@@ -305,7 +309,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 5d4970a..1c46e17 100644<br>--- a/main/stream.c<br>+++ b/main/stream.c<br>@@ -297,18 +297,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>@@ -393,13 +401,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: merged </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: 2 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Matthew Fredrickson <creslin@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>