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










<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
 <p style="margin-top: 0;">On October 3rd, 2013, 6:33 p.m. UTC, <b>Matt Jordan</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/2858/diff/3/?file=46938#file46938line54" style="color: black; font-weight: bold; text-decoration: underline;">/branches/12/res/res_pjsip_header_funcs.c</a>
    <span style="font-weight: normal;">

     (Diff revision 3)

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



 
 

 <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">54</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><enum name="remove"><para>Removes all instances of previously added headers whose names match</span></pre></td>
  </tr>

  <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">55</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><replaceable>name</replaceable>.</span></pre></td>
  </tr>

  <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">56</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span>A <literal>*</literal> may be appended to <replaceable>name</replaceable> to</span></pre></td>
  </tr>

  <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">57</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span>remove all headers <emphasis>beginning with</emphasis> <replaceable>name</replaceable>.</span></pre></td>
  </tr>

  <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">58</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span>A single <literal>*</literal> may be provided for <replaceable>name</replaceable></span></pre></td>
  </tr>

  <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">59</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span>to clear <emphasis>all</emphasis> previously added headers.</span></pre></td>
  </tr>

  <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">60</font></th>
    <td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="cm"><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span><span class="tb">  </span></para></enum></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;">It may be worthwhile adding a <note> to this that states that reading PJSIP_HEADER with the remove option will still remove the headers. That can be done before commit however.</pre>
 </blockquote>



 <p>On October 3rd, 2013, 8:25 p.m. UTC, <b>George Joseph</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;">Just confirming... the same thread that PJSIP_HEADER will be called from will also call the supplemental session callbacks?  If you allow me to say "Matt said so" I'll remove the locks. :)

Since I don't have commit access, I'll add the note, fix the formatting and re-upload the patch.  I ran indent and didn't see anything obvious in the formatting so let me know what should be fixed.</pre>
 </blockquote>





 <p>On October 3rd, 2013, 8:47 p.m. UTC, <b>Joshua Colp</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;">Oh now I understand why you lock. Locking in the PJSIP architecture is so uncommon. Yeah, this code may work as-is but it's not obeying the approach set out. Operations exist as tasks which are pushed onto a task queue for the session itself. This ensures that operations for the session are serialized, and also guarantees that multiple things aren't operating on a session at the same time. media_offer_write would be a good thing to use as a basis.</pre>
 </blockquote>





 <p>On October 3rd, 2013, 10:13 p.m. UTC, <b>George Joseph</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;">The purpose of the lock was to keep the dialplan function from manipulating the header list at the same time as the supplemental callbacks.  

On an incoming channel I still have to use the supp callback and a list because I don't see any way to retrieve an arbitrary header other than in a supp callback.  They're not saved anywhere. I suppose that the incoming callback will always be executed before any dialplan function could be so I could remove the locking.

As for outgoing... media_offer_write has the luxury of having specific well-known structures to manipulate (req_caps and override_prefs) so it can save it's data directly in the session any time the dialplan function is called and the rest of the stack knows what to do with it.  Unless I'm missing something, at the time a pre-dial-handler is called, pjsip_hdr hasn't been created yet so there's no place to store arbitrary headers and no code anywhere that would know what to do with them.  Hence accumulating headers in a session datastore and having the outgoing supp callback add them to the pjsip_msg.  Again, if there's no possibility of the dialplan function running at the same time as the callback, I'll remove the locking.

</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;">I'm not referring to how you do it (list) but where you do it. While a lock does provide the guarantee that two threads can't access it this approach isn't used in the PJSIP architecture overall. Stuff is queued as a task and only one task can execute on the session at a time, this doesn't require a lock for the list but still guarantees that no other thread will access it at the same time. Instead of introducing locking and blurring the line I'd prefer to continue using the task approach.</pre>
<br />




<p>- Joshua</p>


<br />
<p>On September 30th, 2013, 9:15 p.m. UTC, George Joseph 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.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
 <tr>
  <td>

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


<p style="color: grey;"><i>Updated Sept. 30, 2013, 9:15 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-22498">ASTERISK-22498</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;">For PJSIP_HEADER, an incoming supplemental session callback is registered that takes the pjsip_hdrs from the incoming session and stores them in a linked list in the session datastore.  Calls to PJSIP_HEADER traverse over the list and return the nth matching header where 'n' is the 'number' argument to the function.

For PJSIPAddHeader, the first call creates a datastore and linked list and adds the datastore to the session.  The header is then created as a pjsip_hdr and added to the list.  An outgoing supplemental session callback then traverses the list and adds the headers to the outgoing pjsip_msg.

For PJSIPRemoveHeader, the list created with PJSIPAddHeader is traversed and all matching entries are removed.  As with SIPRemoveHeader, an empty arguments removes all headers previously added.

Rather than cloning the incoming pjsip_msg or using pjsip_msg to accumulate the outgoing headers, I used a simple AST_LIST. There was a lot of overhead with the clone functions and some tricky behavior with the pjsip_msg/pjsip_hdr internal lists. Using the AST_LISTs cut down on both instructions and memory.  

All memory allocation is from the pj_pool attached to the session.</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;">Tested successfully...
PJSIP_HEADER return the full value of nth specified header from either the incoming session, or headers previously added to the outgoing session by PJSIPHeader.
PJSIP_HEADER fails if there was no header specified in the function call.
PJSIP_HEADER fails if there was no datastore on the incoming session (should never happen).
PJSIP_HEADER fails if the nth header wasn't found.

PJSIPAddHeader adds a pjsip_hdr structure to the linked list when the input string is properly formatted as "header_name:\s*header_value".
PJSIPAddHeader fails if no ':' was found in the input string.
PJSIPAddHeader fails if after parsing either the header name or value is empty.

PJSIPRemoveHeader removes all matching headers from the linked list when a partial header name is specified.
PJSIPRemoveHeader removes all matching headers from the linked list when a full header is specified with a trailing ':'.
PJSIPRemoveHeader removes all previously added header from the linked list when no header is specified.
PJSIPRemoveHeader returns successfully (silently) if there was no linked list.


</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/res_pjsip_header_funcs.c <span style="color: grey">(PRE-CREATION)</span></li>

</ul>

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







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








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