<p>Richard Mudgett <strong>posted comments</strong> on this change.</p><p><a href="https://gerrit.asterisk.org/7833">View Change</a></p><p>Patch set 1:<span style="border-radius: 3px; display: inline-block; margin: 0 2px; padding: 4px;background-color: #ffd4d4;">Code-Review -1</span></p><p>(15 comments)</p><ul style="list-style: none; padding-left: 20px;"><li><p><a href="https://gerrit.asterisk.org/#/c/7833/1/res/res_stasis.c">File res/res_stasis.c:</a></p><ul style="list-style: none; padding-left: 20px;"><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/res_stasis.c@1615">Patch Set #1, Line 1615:</a> <code style="font-family:monospace,monospace">        ao2_ref(app, -1);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">It might be best if this unref was done after cleanup() just in case there is some unexpected locking relationship with the apps_registry container.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/res_stasis.c@1625">Patch Set #1, Line 1625:</a> <code style="font-family:monospace,monospace">     AST_RWLIST_RDLOCK(&event_sources);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">need write lock not read lock</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/res_stasis.c@1778">Patch Set #1, Line 1778:</a> </p><p><blockquote style="border-left: 1px solid #aaa; margin: 10px 0; padding: 0 10px;"><pre style="font-family: monospace,monospace; white-space: pre-wrap;">          if (handler) {<br>                        res = handler(app, uri, event_source);<br>                }<br></pre></blockquote></p><ul><li>The handling of res is not equivalent.  Previous code aborted the loop by returning res if res was not 0 (STASIS_ASR_OK).</li></ul><ul><li>The test for handler != NULL is loop invariant and could be made a condition of even executing the loop.</li></ul><pre style="font-family: monospace,monospace; white-space: pre-wrap;">if (handler) {<br>   for () {<br>      ...<br>      res = handler();<br>      if (res != STASIS_ASR_OK) {<br>         break;<br>      }<br>   }<br>}</pre><p style="white-space: pre-wrap; word-wrap: break-word;">or instead of breaking out of the loop and retesting res you could exit early:</p><p style="white-space: pre-wrap; word-wrap: break-word;">ao2_ref(app, -1);<br>return res;</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/res_stasis.c@1926">Patch Set #1, Line 1926:</a> </p><p><blockquote style="border-left: 1px solid #aaa; margin: 10px 0; padding: 0 10px;"><pre style="font-family: monospace,monospace; white-space: pre-wrap;">      if (json_variables) {<br>         struct ast_json *json_value = ast_json_string_create(event_name);<br><br>           if (json_value && !ast_json_object_set(blob, "eventname", json_value)) {<br>                    blob = ast_json_ref(json_variables);<br>          }<br>     } else {<br>              blob = ast_json_pack("{ss}", "eventname", event_name);<br>    }<br><br>   if (!blob) {<br>          ast_log(LOG_ERROR, "Failed to initialize blob\n");<br><br>                return res;<br>   }<br></pre></blockquote></p><p style="white-space: pre-wrap; word-wrap: break-word;">This does not appear to be equivalent code to setup blob from json_variables.</p></li></ul></li><li><p><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c">File res/stasis/app.c:</a></p><ul style="list-style: none; padding-left: 20px;"><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@932">Patch Set #1, Line 932:</a> <code style="font-family:monospace,monospace">struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model)</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">A follow on patch is needed to fix app_create() leaking a partially created app if it fails to get fully initialized.  See app_shutdown() for cleanup.</p><p style="white-space: pre-wrap; word-wrap: break-word;">In fact, the circular refs in app->bridge_router and app->router could likely cause app to leak on many off-nominal failure paths by callers even on successful creation.  Not sure it is even possible to clean up in these cases.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@956">Patch Set #1, Line 956:</a> <code style="font-family:monospace,monospace">    if (!app->forwards || !app->topic || !app->bridge_router) {</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">You can combine app->forwards and app->topic this way.</p><p style="white-space: pre-wrap; word-wrap: break-word;">However, app->bridge_router supposedly has its own circular ref to app so app_dtor() asserts that app->bridge_router == NULL as well as app->router == NULL.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1041">Patch Set #1, Line 1041:</a> </p><p><blockquote style="border-left: 1px solid #aaa; margin: 10px 0; padding: 0 10px;"><pre style="font-family: monospace,monospace; white-space: pre-wrap;">     if (app->data) {<br>           ao2_ref(app->data, +1);<br>            data = app->data;<br>  }<br></pre></blockquote></p><p style="white-space: pre-wrap; word-wrap: break-word;">This is<br>data = ao2_bump(app->data);<br>so data won't need initializing to NULL either.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1054">Patch Set #1, Line 1054:</a> <code style="font-family:monospace,monospace"> ao2_ref(data, -1);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">data could be NULL so<br>ao2_cleanup(data);</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1237">Patch Set #1, Line 1237:</a> </p><p><blockquote style="border-left: 1px solid #aaa; margin: 10px 0; padding: 0 10px;"><pre style="font-family: monospace,monospace; white-space: pre-wrap;">          id = ast_json_string_create(forwards->id);<br><br>               switch (forwards->forward_type) {<br></pre></blockquote></p><p style="white-space: pre-wrap; word-wrap: break-word;">id is leaked if no switch case is taken.  Adding a default case would remove the compile time safety of an enum as a switch selector.</p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">id = ast_json_string_create()<br>switch (forwards->forward_type) {<br>case FORWARD_CHANNEL:<br>   appen_res = ast_json_array_apend(channels, ast_json_ref(id));<br>   break;<br>...<br>}<br>ast_json_unref(id);</pre></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1265">Patch Set #1, Line 1265:</a> <code style="font-family:monospace,monospace">int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">Missed this function.  It corresponds to the bridge and endpoint versions done in this patch.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1336">Patch Set #1, Line 1336:</a> <code style="font-family:monospace,monospace">         return -1;</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">Missed the unlock here</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1441">Patch Set #1, Line 1441:</a> <code style="font-family:monospace,monospace">  ao2_ref(forwards, -1);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">Unlock app->forwards before unref here instead of earlier so the manipulation of forwards is done under the lock.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1469">Patch Set #1, Line 1469:</a> </p><p><blockquote style="border-left: 1px solid #aaa; margin: 10px 0; padding: 0 10px;"><pre style="font-family: monospace,monospace; white-space: pre-wrap;">int app_is_subscribed_bridge_id(struct stasis_app *app, const char *bridge_id)<br>{<br>        struct app_forwards *forwards;<br><br>      if (ast_strlen_zero(bridge_id)) {<br>             bridge_id = BRIDGE_ALL;<br>       }<br><br>   forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY);<br>     ao2_cleanup(forwards);<br><br>      return forwards != NULL;<br>}<br></pre></blockquote></p><p style="white-space: pre-wrap; word-wrap: break-word;">I think this bug fix change deserves special mention in the commit message as we can search the container twice if it isn't found.  Either that or put it in a separate patch.</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1499">Patch Set #1, Line 1499:</a> <code style="font-family:monospace,monospace"> SCOPED_AO2LOCK(lock, app->forwards);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">This was left in</p></li><li><p style="margin-bottom: 4px;"><a href="https://gerrit.asterisk.org/#/c/7833/1/res/stasis/app.c@1539">Patch Set #1, Line 1539:</a> <code style="font-family:monospace,monospace">   ao2_ref(forwards, -1);</code></p><p style="white-space: pre-wrap; word-wrap: break-word;">Unlock app->forwards before unref here instead of earlier so the manipulation of forwards is done under the lock.</p></li></ul></li></ul><p>To view, visit <a href="https://gerrit.asterisk.org/7833">change 7833</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/7833"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: comment </div>
<div style="display:none"> Gerrit-Change-Id: I4ce67120583a446babf9adeec678b71d37fcd9e5 </div>
<div style="display:none"> Gerrit-Change-Number: 7833 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-Comment-Date: Sun, 07 Jan 2018 00:28:01 +0000 </div>
<div style="display:none"> Gerrit-HasComments: Yes </div>