<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/2242/">https://reviewboard.asterisk.org/r/2242/</a>
     </td>
    </tr>
   </table>
   <br />








<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
 <p style="margin-top: 0;">On January 10th, 2013, 1 p.m., <b>David Lee</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  



<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/2242/diff/2/?file=32638#file32638line143" style="color: black; font-weight: bold; text-decoration: underline;">/trunk/include/asterisk/taskprocessor.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="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">struct ast_taskprocessor_listener_callbacks {</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">143</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="k">struct</span> <span class="n">ast_taskprocessor_listener</span> <span class="p">{</span></pre></td>
  </tr>

 </tbody>

</table>

  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I think I see what you&#39;re doing, and I think you&#39;re exposing too much through the API.
 * Make ast_taskprocessor_listener and opaque struct
   * add accessor functions if you need any
 * get rid of the private_data alloc and free callbacks; just put that data in the taskprocessor struct</pre>
 </blockquote>



 <p>On January 10th, 2013, 2:59 p.m., <b>Mark Michelson</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I had gone down the road of making taskprocessor listener an opaque struct, but I didn&#39;t think it was really worth it when I originally coded this.

I have to disagree with your suggestion of putting the private data in the taskprocessor struct. IMO, the taskprocessor and the listener are two separate entities, and in the case of the two taskprocessor listeners that exist now, the default listener and the threadpool, the private data is intrinsic to the listener, not the taskprocessor. For instance, the default taskprocessor listener runs a thread that executes the tasks in the taskprocessor. Information about the thread and its execution belongs in the listener, not the taskprocessor. I guess you&#39;re seeing it more that the listener is a part of the taskprocessor and so having the private data in the taskprocessor makes just as much sense as having it in the listener.

I&#39;d be willing to get rid of the alloc callback potentially. ast_taskprocessor_listener_alloc() could just take another parameter that is the private data. The reason it works the way it does right now is due to some chicken-and-egg logic that exists. The private data needs a reference to the taskprocessor so it can execute tasks, the taskprocessor listener owns the private data, and the taskprocessor has a reference to the taskprocessor listener. My solution was to add an allocation function so that listener private data could be allocated once everything else in the taskprocessor and its listener was set up. If I get rid of the alloc callback, then I can just let the private data get its reference to the taskprocessor callback in the listener&#39;s start() callback.</pre>
 </blockquote>







</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Yeah; I don&#39;t think I really understood what you were doing there.

I still think getting rid of the alloc/free callbacks would be a Good Thing(TM). Passing the private data pointer in the _alloc() call makes more sense to me.</pre>
<br />

<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
 <p style="margin-top: 0;">On January 10th, 2013, 1 p.m., <b>David Lee</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  



<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/2242/diff/2/?file=32641#file32641line66" style="color: black; font-weight: bold; text-decoration: underline;">/trunk/main/threadpool.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; "></pre></td>
   <td colspan="2"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">struct ast_threadpool {</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">66</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">        <span class="k">struct</span> <span class="n">ast_taskprocessor</span> <span class="o">*</span><span class="n">tps</span><span class="p">;</span></pre></td>
  </tr>

 </tbody>

</table>

  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I think rather than using a taskprocessor here, maybe what you really want to do is extract the shared threadpool/taskprocessor code into a third thing.</pre>
 </blockquote>



 <p>On January 10th, 2013, 2:59 p.m., <b>Mark Michelson</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Can you elaborate a bit? &quot;A third thing&quot; is not very descriptive of what you are trying to convey.</pre>
 </blockquote>







</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Sure. By the time I wrote that, my brain was in a code-review induced stupor.

Basically, instead of having a default-behavior taskprocessor and a specialized-behavior taskprocessor, what if you extracted out a thread-safe queue that you can attach listeners to. You would reuse the queue for both taskprocessor and threadpool, without having different kinds of taskprocessors.

Coming at this fresh, though, I may be simultaneously overthinking (excessive object design) and underthinking (how would you do that in C?).</pre>
<br />




<p>- David</p>


<br />
<p>On January 7th, 2013, 4:20 p.m., Mark Michelson wrote:</p>






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

<div>Review request for Asterisk Developers.</div>
<div>By Mark Michelson.</div>


<p style="color: grey;"><i>Updated Jan. 7, 2013, 4:20 p.m.</i></p>




<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;">This review adds a generic threadpool for Asterisk.

The threadpool implementation here is very similar to the one implemented in Asterisk SCF. Since this is implemented in C, the &quot;is a&quot; semantics offered by C++ are not available, so that had to be worked around.

The threadpool, when created, creates a taskprocessor. The threadpool itself exists as the private data on a taskprocessor listener. In this way, the threadpool can react to changes on the taskprocessor by informing its threadpool listener.

The threadpool informs its listeners of various changes:
- When a task gets pushed into the threadpool
- When the threadpool&#39;s task list has become empty
- When the state of the threadpool&#39;s threads has changed, such as when an active thread goes idle or an idle thread is destroyed.

The threadpool listener can react to these changes as it sees fit. This allows for different policies to be adopted by different modules.

The offers some options for automatic behavior for common forms of operation. At allocation, an idle timeout can be specified in order to allow for idle threads to automatically get removed from the threadpool once they have been idle for a certain amount of time. Also, an automatic increment can be specified if the threadpool has tasks added to it and no idle threads are available to handle the task. With these, it may be possible for listeners only to intervene in certain situations. More options can possibly be added if they are not too policy-specific.

This set of changes is dependent on the set of taskprocessor changes introduced in https://reviewboard.asterisk.org/r/2200 . Since these changes were developed in the same branch as the taskprocessor changes, it means that all the taskprocessor changes are also included in this review. While there are minor changes in the taskprocessor code here as compared to the code in review 2200, they are very minor changes, and so close scrutiny of the taskprocessor changes is not as important as the threadpool code itself.</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;">A suite of unit tests have been added to ensure that the threadpool works as expected. They all pass.</pre>
  </td>
 </tr>
</table>



<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-20691">ASTERISK-20691</a>


</div>


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

 <li>/trunk/main/threadpool.c <span style="color: grey">(PRE-CREATION)</span></li>

 <li>/trunk/include/asterisk/taskprocessor.h <span style="color: grey">(378146)</span></li>

 <li>/trunk/include/asterisk/threadpool.h <span style="color: grey">(PRE-CREATION)</span></li>

 <li>/trunk/main/taskprocessor.c <span style="color: grey">(378146)</span></li>

 <li>/trunk/tests/test_taskprocessor.c <span style="color: grey">(PRE-CREATION)</span></li>

 <li>/trunk/tests/test_threadpool.c <span style="color: grey">(PRE-CREATION)</span></li>

</ul>

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




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








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