<html>
 <body>
  <div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
   <table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 solid;">
    <tr>
     <td>
      This is an automatically generated e-mail. To reply, visit:
      <a href="https://reviewboard.asterisk.org/r/3908/">https://reviewboard.asterisk.org/r/3908/</a>
     </td>
    </tr>
   </table>
   <br />











<div>




<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
 <thead>
  <tr>
   <th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
    <a href="https://reviewboard.asterisk.org/r/3908/diff/2/?file=66659#file66659line77" style="color: black; font-weight: bold; text-decoration: underline;">/branches/12/res/stasis/command.h</a>
    <span style="font-weight: normal;">

     (Diff revision 2)

    </span>
   </th>
  </tr>
 </thead>

 <tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
  <tr>

   <td colspan="4"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">int command_join(struct stasis_app_command *command);</pre></td>

  </tr>
 </tbody>



 
 

 <tbody>

  <tr>
    <th bgcolor="#b1ebb0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
    <th bgcolor="#b1ebb0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">77</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="kt">void</span> <span class="nf">command_data_free</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">data</span><span class="p">);</span></pre></td>
  </tr>

 </tbody>

</table>

<pre style="margin-left: 2em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Remove this special function and use ast_free_ptr instead.  This is what ast_free_ptr is for.</pre>
</div>
<br />

<div>




<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
 <thead>
  <tr>
   <th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
    <a href="https://reviewboard.asterisk.org/r/3908/diff/2/?file=66659#file66659line84" style="color: black; font-weight: bold; text-decoration: underline;">/branches/12/res/stasis/command.h</a>
    <span style="font-weight: normal;">

     (Diff revision 2)

    </span>
   </th>
  </tr>
 </thead>

 <tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
  <tr>

   <td colspan="4"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">int command_join(struct stasis_app_command *command);</pre></td>

  </tr>
 </tbody>



 
 

 <tbody>

  <tr>
    <th bgcolor="#b1ebb0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
    <th bgcolor="#b1ebb0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">84</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="kt">void</span> <span class="nf">command_data_cleanup</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">data</span><span class="p">);</span></pre></td>
  </tr>

 </tbody>

</table>

<pre style="margin-left: 2em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Remove this special function and use __ao2_cleanup instead.  This is what __ao2_cleanup is for.</pre>
</div>
<br />

<div>




<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
 <thead>
  <tr>
   <th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
    <a href="https://reviewboard.asterisk.org/r/3908/diff/2/?file=66660#file66660line99" style="color: black; font-weight: bold; text-decoration: underline;">/branches/12/res/stasis/command.c</a>
    <span style="font-weight: normal;">

     (Diff revision 2)

    </span>
   </th>
  </tr>
 </thead>

 <tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
  <tr>

   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">static void command_queue_prestart_destroy(void *obj)</pre></td>
   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">void command_invoke(struct stasis_app_command *command,</pre></td>

  </tr>
 </tbody>



 
 

 <tbody>

  <tr>
    <th bgcolor="#f0f0f0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">92</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="kt">int</span> <span class="n">retval</span> <span class="o">=</span> <span class="n">command</span><span class="o">-></span><span class="n">callback</span><span class="p">(</span><span class="n">control</span><span class="p">,</span> <span class="n">chan</span><span class="p">,</span> <span class="n">command</span><span class="o">-></span><span class="n">data</span><span class="p">);</span></pre></td>
    <th bgcolor="#f0f0f0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">99</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="kt">int</span> <span class="n">retval</span> <span class="o">=</span> <span class="n">command</span><span class="o">-></span><span class="n">callback</span><span class="p">(</span><span class="n">control</span><span class="p">,</span> <span class="n">chan</span><span class="p">,</span> <span class="n">command</span><span class="o">-></span><span class="n">data</span><span class="p">);</span></pre></td>
  </tr>

 </tbody>

</table>

<pre style="margin-left: 2em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">You should call the data_destructor here if it is present and then clear the data_destructor pointer.  Otherwise, you are extending the life of the data object possibly too long from what it was before.</pre>
</div>
<br />

<div>




<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
 <thead>
  <tr>
   <th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
    <a href="https://reviewboard.asterisk.org/r/3908/diff/2/?file=66660#file66660line122" style="color: black; font-weight: bold; text-decoration: underline;">/branches/12/res/stasis/command.c</a>
    <span style="font-weight: normal;">

     (Diff revision 2)

    </span>
   </th>
  </tr>
 </thead>

 <tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
  <tr>

   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">static void command_queue_prestart_destroy(void *obj)</pre></td>
   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">void command_invoke(struct stasis_app_command *command,</pre></td>

  </tr>
 </tbody>



 
 

 <tbody>

  <tr>
    <th bgcolor="#f0f0f0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">115</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">command</span><span class="p">)</span> <span class="p">{</span></pre></td>
    <th bgcolor="#f0f0f0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">122</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">command</span><span class="p">)</span> <span class="p">{</span></pre></td>
  </tr>

  <tr>
    <th bgcolor="#f0f0f0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">116</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span></pre></td>
    <th bgcolor="#f0f0f0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">123</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span></pre></td>
  </tr>

  <tr>
    <th bgcolor="#f0f0f0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">117</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="p">}</span></pre></td>
    <th bgcolor="#f0f0f0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">124</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="p">}</span></pre></td>
  </tr>

 </tbody>

</table>

<pre style="margin-left: 2em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Call the data_destructor here if there is one to guarantee that the data will be destroyed regardless of successfully queueing the command.  Otherwise, you could return -1 and the caller would not know if the data was destroyed.

It might be better to have command_create() do this instead if the command object could not be created.  This way the other places that create commands would be covered as well.</pre>
</div>
<br />



<p>- rmudgett</p>


<br />
<p>On August 20th, 2014, 4:21 p.m. CDT, Jonathan Rose wrote:</p>








<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" style="background-image: url('https://reviewboard.asterisk.org/static/rb/images/review_request_box_top_bg.ab6f3b1072c9.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
 <tr>
  <td>

<div>Review request for Asterisk Developers, kmoore, Matt Jordan, and rmudgett.</div>
<div>By Jonathan Rose.</div>


<p style="color: grey;"><i>Updated Aug. 20, 2014, 4:21 p.m.</i></p>







<div style="margin-top: 1.5em;">
 <b style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Bugs: </b>


 <a href="https://issues.asterisk.org/jira/browse/ASTERISK-24147">ASTERISK-24147</a>


</div>



<div style="margin-top: 1.5em;">
 <b style="color: #575012; font-size: 10pt;">Repository: </b>
Asterisk
</div>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
 <table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Here's a basic rundown of what was happening:

1. Stasis application with a channel in it, channel is in a bridge.  Playback actions for the channel are queued, the stasis control is running them.

2. The channel hangs up. Because the stasis control detects a hangup and the depart is expected to be handled when the channel leaves the bridge, the stasis application execution function exits taking the control along with it. When the PBX thread exits, the channel is considered fully hung up and leaves the bridging core. At this point we are running after bridge callbacks with, one of which holds a pointer to a dead control object that we are trying to do all queue actions to along with other things.  This causes the crash.

In order to fix this, I made sure that if the control execution loop is exited without pulling the channel out of the bridge that the channel depart would occur manually and the control would be marked so that the after bridge cb wouldn't attempt to exit the bridge in this case. This wasn't actually causing problems, but Richard and I both have concerns about an after bridge callback attempting to depart a channel from a bridge... it seems a little out there.</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Made sure the crash that was happening no longer occurs

Tested long queues of playback to check what would happen with the additional playbacks.  Each subsequent playback from the one currently running fails (in an expected manner) and reports its failure over stasis.  Nothing too odd there.</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">

 <li>/branches/12/res/stasis/stasis_bridge.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/stasis/control.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/stasis/command.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/stasis/command.h <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/res_stasis_recording.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/res_stasis_playback.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/res_stasis_answer.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/res/res_stasis.c <span style="color: grey">(421424)</span></li>

 <li>/branches/12/include/asterisk/stasis_app_impl.h <span style="color: grey">(421424)</span></li>

</ul>

<p><a href="https://reviewboard.asterisk.org/r/3908/diff/" style="margin-left: 3em;">View Diff</a></p>







  </td>
 </tr>
</table>








  </div>
 </body>
</html>