<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[Freeswitch-trunk][14769] </title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<div id="header">FreeSWITCH Subversion</div>
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://fisheye.freeswitch.org/changelog/FreeSWITCH?cs=14769">14769</a></dd>
<dt>Author</dt> <dd>anthm</dd>
<dt>Date</dt> <dd>2009-09-04 13:34:52 -0500 (Fri, 04 Sep 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>add mutex to deal with small race</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#freeswitchtrunksrcmodapplicationsmod_conferencemod_conferencec">freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunksrcmodapplicationsmod_conferencemod_conferencec"></a>
<div class="modfile"><h4>Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (14768 => 14769)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c        2009-09-04 18:26:15 UTC (rev 14768)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c        2009-09-04 18:34:52 UTC (rev 14769)
</span><span class="lines">@@ -313,9 +313,10 @@
</span><span class="cx">         uint32_t score;
</span><span class="cx">         uint32_t score_iir;
</span><span class="cx">         switch_mutex_t *flag_mutex;
</span><del>-        switch_mutex_t *control_mutex;
</del><ins>+        switch_mutex_t *write_mutex;
</ins><span class="cx">         switch_mutex_t *audio_in_mutex;
</span><span class="cx">         switch_mutex_t *audio_out_mutex;
</span><ins>+        switch_mutex_t *read_mutex;
</ins><span class="cx">         switch_codec_implementation_t orig_read_impl;
</span><span class="cx">         switch_codec_t read_codec;
</span><span class="cx">         switch_codec_t write_codec;
</span><span class="lines">@@ -419,6 +420,10 @@
</span><span class="cx"> static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event);
</span><span class="cx"> static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event);
</span><span class="cx"> 
</span><ins>+
+#define lock_member(_member) switch_mutex_lock(_member-&gt;write_mutex); switch_mutex_lock(_member-&gt;read_mutex)
+#define unlock_member(_member) switch_mutex_unlock(_member-&gt;read_mutex); switch_mutex_unlock(_member-&gt;write_mutex)
+
</ins><span class="cx"> static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event)
</span><span class="cx"> {
</span><span class="cx">         switch_status_t status = SWITCH_STATUS_SUCCESS;
</span><span class="lines">@@ -478,8 +483,8 @@
</span><span class="cx">         if (member == NULL || other_member == NULL || member-&gt;relationships == NULL)
</span><span class="cx">                 return NULL;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
-        switch_mutex_lock(other_member-&gt;control_mutex);
</del><ins>+        lock_member(member);
+        lock_member(other_member);
</ins><span class="cx"> 
</span><span class="cx">         for (rel = member-&gt;relationships; rel; rel = rel-&gt;next) {
</span><span class="cx">                 if (rel-&gt;id == other_member-&gt;id) {
</span><span class="lines">@@ -492,8 +497,8 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        switch_mutex_unlock(other_member-&gt;control_mutex);
-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(other_member);
+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         return rel ? rel : global;
</span><span class="cx"> }
</span><span class="lines">@@ -557,10 +562,10 @@
</span><span class="cx"> 
</span><span class="cx">         rel-&gt;id = id;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         rel-&gt;next = member-&gt;relationships;
</span><span class="cx">         member-&gt;relationships = rel;
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         return rel;
</span><span class="cx"> }
</span><span class="lines">@@ -574,7 +579,7 @@
</span><span class="cx">         if (member == NULL || id == 0)
</span><span class="cx">                 return status;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         for (rel = member-&gt;relationships; rel; rel = rel-&gt;next) {
</span><span class="cx">                 if (rel-&gt;id == id) {
</span><span class="cx">                         /* we just forget about rel here cos it was allocated by the member's pool 
</span><span class="lines">@@ -588,7 +593,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 last = rel;
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         return status;
</span><span class="cx"> }
</span><span class="lines">@@ -608,7 +613,7 @@
</span><span class="cx">         switch_mutex_lock(conference-&gt;mutex);
</span><span class="cx">         switch_mutex_lock(member-&gt;audio_in_mutex);
</span><span class="cx">         switch_mutex_lock(member-&gt;audio_out_mutex);
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         switch_mutex_lock(conference-&gt;member_mutex);
</span><span class="cx"> 
</span><span class="cx">         switch_clear_flag(conference, CFLAG_DESTRUCT);
</span><span class="lines">@@ -703,7 +708,7 @@
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx">         switch_mutex_unlock(member-&gt;audio_out_mutex);
</span><span class="cx">         switch_mutex_unlock(member-&gt;audio_in_mutex);
</span><span class="cx"> 
</span><span class="lines">@@ -725,18 +730,18 @@
</span><span class="cx">         switch_assert(conference != NULL);
</span><span class="cx">         switch_assert(member != NULL);
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member_fnode = member-&gt;fnode;
</span><span class="cx">         member_sh = member-&gt;sh;
</span><span class="cx">         member-&gt;fnode = NULL;
</span><span class="cx">         member-&gt;sh = NULL;
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_mutex_lock(conference-&gt;mutex);
</span><span class="cx">         switch_mutex_lock(conference-&gt;member_mutex);
</span><span class="cx">         switch_mutex_lock(member-&gt;audio_in_mutex);
</span><span class="cx">         switch_mutex_lock(member-&gt;audio_out_mutex);
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         switch_clear_flag(member, MFLAG_INTREE);
</span><span class="cx"> 
</span><span class="cx">         for (imember = conference-&gt;members; imember; imember = imember-&gt;next) {
</span><span class="lines">@@ -832,7 +837,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx">         switch_mutex_unlock(conference-&gt;member_mutex);
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx">         switch_mutex_unlock(member-&gt;audio_out_mutex);
</span><span class="cx">         switch_mutex_unlock(member-&gt;audio_in_mutex);
</span><span class="cx">         switch_mutex_unlock(conference-&gt;mutex);
</span><span class="lines">@@ -1407,7 +1412,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;energy_level += 200;
</span><span class="cx">         if (member-&gt;energy_level &gt; 3000) {
</span><span class="cx">                 member-&gt;energy_level = 3000;
</span><span class="lines">@@ -1420,7 +1425,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;energy_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Energy level %d&quot;, member-&gt;energy_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1434,7 +1439,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;energy_level = member-&gt;conference-&gt;energy_level;
</span><span class="cx"> 
</span><span class="cx">         if (test_eflag(member-&gt;conference, EFLAG_ENERGY_LEVEL) &amp;&amp;
</span><span class="lines">@@ -1444,7 +1449,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;energy_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Energy level %d&quot;, member-&gt;energy_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1458,7 +1463,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;energy_level -= 100;
</span><span class="cx">         if (member-&gt;energy_level &lt; 0) {
</span><span class="cx">                 member-&gt;energy_level = 0;
</span><span class="lines">@@ -1471,7 +1476,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;energy_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Energy level %d&quot;, member-&gt;energy_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1485,7 +1490,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_out_level++;
</span><span class="cx">         switch_normalize_volume(member-&gt;volume_out_level);
</span><span class="cx"> 
</span><span class="lines">@@ -1496,7 +1501,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_out_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Volume level %d&quot;, member-&gt;volume_out_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1510,7 +1515,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_out_level = 0;
</span><span class="cx"> 
</span><span class="cx">         if (test_eflag(member-&gt;conference, EFLAG_VOLUME_LEVEL) &amp;&amp;
</span><span class="lines">@@ -1520,7 +1525,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_out_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Volume level %d&quot;, member-&gt;volume_out_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1534,7 +1539,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_out_level--;
</span><span class="cx">         switch_normalize_volume(member-&gt;volume_out_level);
</span><span class="cx"> 
</span><span class="lines">@@ -1545,7 +1550,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_out_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Volume level %d&quot;, member-&gt;volume_out_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1559,7 +1564,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_in_level++;
</span><span class="cx">         switch_normalize_volume(member-&gt;volume_in_level);
</span><span class="cx"> 
</span><span class="lines">@@ -1570,7 +1575,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_in_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Gain level %d&quot;, member-&gt;volume_in_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1584,7 +1589,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_in_level = 0;
</span><span class="cx"> 
</span><span class="cx">         if (test_eflag(member-&gt;conference, EFLAG_GAIN_LEVEL) &amp;&amp;
</span><span class="lines">@@ -1594,7 +1599,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_in_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Gain level %d&quot;, member-&gt;volume_in_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1608,7 +1613,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         member-&gt;volume_in_level--;
</span><span class="cx">         switch_normalize_volume(member-&gt;volume_in_level);
</span><span class="cx"> 
</span><span class="lines">@@ -1619,7 +1624,7 @@
</span><span class="cx">                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, &quot;New-Level&quot;, &quot;%d&quot;, member-&gt;volume_in_level);
</span><span class="cx">                 switch_event_fire(&amp;event);
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         switch_snprintf(msg, sizeof(msg), &quot;Gain level %d&quot;, member-&gt;volume_in_level);
</span><span class="cx">         conference_member_say(member, msg, 0);
</span><span class="lines">@@ -1766,9 +1771,11 @@
</span><span class="cx"> 
</span><span class="cx">         while (switch_test_flag(member, MFLAG_RUNNING) &amp;&amp; switch_channel_ready(channel)) {
</span><span class="cx"> 
</span><del>-                if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
</del><ins>+                switch_mutex_lock(member-&gt;read_mutex);
+
+                if (switch_channel_ready(channel) &amp;&amp; switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
</ins><span class="cx">                         switch_yield(100000);
</span><del>-                        continue;
</del><ins>+                        goto do_continue;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1777,7 +1784,7 @@
</span><span class="cx"> 
</span><span class="cx">                 /* end the loop, if appropriate */
</span><span class="cx">                 if (!SWITCH_READ_ACCEPTABLE(status) || !switch_test_flag(member, MFLAG_RUNNING)) {
</span><del>-                        break;
</del><ins>+                        goto do_break;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 if (switch_test_flag(read_frame, SFF_CNG)) {
</span><span class="lines">@@ -1798,7 +1805,7 @@
</span><span class="cx">                                         }
</span><span class="cx">                                 }
</span><span class="cx">                         }
</span><del>-                        continue;
</del><ins>+                        goto do_continue;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 energy_level = member-&gt;energy_level;
</span><span class="lines">@@ -1940,12 +1947,21 @@
</span><span class="cx">                                 ok = switch_buffer_write(member-&gt;audio_buffer, data, datalen);
</span><span class="cx">                                 switch_mutex_unlock(member-&gt;audio_in_mutex);
</span><span class="cx">                                 if (!ok) {
</span><del>-                                        break;
</del><ins>+                                        goto do_break;
</ins><span class="cx">                                 }
</span><span class="cx">                         }
</span><span class="cx">                 }
</span><ins>+
+        do_continue:
+
+                switch_mutex_unlock(member-&gt;read_mutex);
+                
</ins><span class="cx">         }
</span><span class="cx"> 
</span><ins>+ do_break:
+
+        switch_mutex_unlock(member-&gt;read_mutex);
+
</ins><span class="cx">         switch_resample_destroy(&amp;member-&gt;read_resampler);
</span><span class="cx">         switch_clear_flag_locked(member, MFLAG_ITHREAD);
</span><span class="cx"> 
</span><span class="lines">@@ -2123,12 +2139,14 @@
</span><span class="cx">                 switch_size_t file_sample_len = csamples;
</span><span class="cx">                 switch_size_t file_data_len = file_sample_len * 2;
</span><span class="cx"> 
</span><ins>+
+                switch_mutex_lock(member-&gt;write_mutex);
+
</ins><span class="cx">                 if (switch_test_flag(member, MFLAG_RESTART)) {
</span><ins>+                        switch_mutex_unlock(member-&gt;write_mutex);
</ins><span class="cx">                         goto top;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-                switch_mutex_lock(member-&gt;control_mutex);
-
</del><span class="cx">                 if (switch_core_session_dequeue_event(member-&gt;session, &amp;event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
</span><span class="cx">                         if (event-&gt;event_id == SWITCH_EVENT_MESSAGE) {
</span><span class="cx">                                 char *from = switch_event_get_header(event, &quot;from&quot;);
</span><span class="lines">@@ -2330,7 +2348,7 @@
</span><span class="cx">                         switch_clear_flag_locked(member, MFLAG_FLUSH_BUFFER);
</span><span class="cx">                 }
</span><span class="cx">                 
</span><del>-                switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+                switch_mutex_unlock(member-&gt;write_mutex);
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">                 if (switch_core_session_private_event_count(member-&gt;session)) {
</span><span class="lines">@@ -2347,8 +2365,9 @@
</span><span class="cx">                         switch_cond_next();
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-        }                                                        /* Rinse ... Repeat */
</del><ins>+        } /* Rinse ... Repeat */
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">         if (member-&gt;digit_stream != NULL) {
</span><span class="cx">                 switch_ivr_digit_stream_destroy(&amp;member-&gt;digit_stream);
</span><span class="cx">         }
</span><span class="lines">@@ -2415,10 +2434,11 @@
</span><span class="cx">         member-&gt;mux_frame = switch_core_alloc(member-&gt;pool, member-&gt;frame_size);
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-        switch_mutex_init(&amp;member-&gt;control_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</del><ins>+        switch_mutex_init(&amp;member-&gt;write_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</ins><span class="cx">         switch_mutex_init(&amp;member-&gt;flag_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</span><span class="cx">         switch_mutex_init(&amp;member-&gt;audio_in_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</span><span class="cx">         switch_mutex_init(&amp;member-&gt;audio_out_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</span><ins>+        switch_mutex_init(&amp;member-&gt;read_mutex, SWITCH_MUTEX_NESTED, rec-&gt;pool);
</ins><span class="cx"> 
</span><span class="cx">         /* Setup an audio buffer for the incoming audio */
</span><span class="cx">         if (switch_buffer_create_dynamic(&amp;member-&gt;audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, 0) != SWITCH_STATUS_SUCCESS) {
</span><span class="lines">@@ -2575,7 +2595,7 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return count;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         if (stop == FILE_STOP_ALL) {
</span><span class="cx">                 for (nptr = member-&gt;fnode; nptr; nptr = nptr-&gt;next) {
</span><span class="lines">@@ -2589,7 +2609,7 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         return count;
</span><span class="cx"> }
</span><span class="lines">@@ -2610,10 +2630,10 @@
</span><span class="cx">                         const char *p;
</span><span class="cx">                         for (p = dtmf; p &amp;&amp; *p; p++) {
</span><span class="cx">                                 switch_dtmf_t digit = { *p, SWITCH_DEFAULT_DTMF_DURATION};
</span><del>-                                switch_mutex_lock(imember-&gt;control_mutex);
</del><ins>+                                lock_member(imember);
</ins><span class="cx">                                 switch_core_session_kill_channel(imember-&gt;session, SWITCH_SIG_BREAK);
</span><span class="cx">                                 switch_core_session_send_dtmf(imember-&gt;session, &amp;digit);
</span><del>-                                switch_mutex_unlock(imember-&gt;control_mutex);
</del><ins>+                                unlock_member(imember);
</ins><span class="cx">                         }
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="lines">@@ -2802,14 +2822,14 @@
</span><span class="cx">         fnode-&gt;file = switch_core_strdup(fnode-&gt;pool, file);
</span><span class="cx">         /* Queue the node */
</span><span class="cx">         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member-&gt;session), SWITCH_LOG_DEBUG, &quot;Queueing file '%s' for play\n&quot;, file);
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         for (nptr = member-&gt;fnode; nptr &amp;&amp; nptr-&gt;next; nptr = nptr-&gt;next);
</span><span class="cx">         if (nptr) {
</span><span class="cx">                 nptr-&gt;next = fnode;
</span><span class="cx">         } else {
</span><span class="cx">                 member-&gt;fnode = fnode;
</span><span class="cx">         }
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx">         status = SWITCH_STATUS_SUCCESS;
</span><span class="cx"> 
</span><span class="cx">   done:
</span><span class="lines">@@ -2867,7 +2887,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /* Queue the node */
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         for (nptr = member-&gt;fnode; nptr &amp;&amp; nptr-&gt;next; nptr = nptr-&gt;next);
</span><span class="cx"> 
</span><span class="cx">         if (nptr) {
</span><span class="lines">@@ -2893,7 +2913,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         switch_core_speech_feed_tts(fnode-&gt;sh, text, &amp;flags);
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         status = SWITCH_STATUS_SUCCESS;
</span><span class="cx"> 
</span><span class="lines">@@ -3196,12 +3216,12 @@
</span><span class="cx">         if (member == NULL)
</span><span class="cx">                 return SWITCH_STATUS_GENERR;
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         switch_clear_flag(member, MFLAG_RUNNING);
</span><span class="cx">         switch_set_flag_locked(member, MFLAG_KICKED);
</span><span class="cx"> 
</span><span class="cx">         switch_core_session_kill_channel(member-&gt;session, SWITCH_SIG_BREAK);
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx">         if (stream != NULL) {
</span><span class="cx">                 stream-&gt;write_function(stream, &quot;OK kicked %u\n&quot;, member-&gt;id);
</span><span class="cx">         }
</span><span class="lines">@@ -3231,10 +3251,10 @@
</span><span class="cx">                 return SWITCH_STATUS_GENERR;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+        lock_member(member);
</ins><span class="cx">         switch_core_session_kill_channel(member-&gt;session, SWITCH_SIG_BREAK);
</span><span class="cx">         switch_core_session_send_dtmf_string(member-&gt;session, (char *) data);
</span><del>-        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+        unlock_member(member);
</ins><span class="cx"> 
</span><span class="cx">         if (stream != NULL) {
</span><span class="cx">                 stream-&gt;write_function(stream, &quot;OK sent %s to %u\n&quot;, (char *) data, member-&gt;id);
</span><span class="lines">@@ -3259,9 +3279,9 @@
</span><span class="cx">                 return SWITCH_STATUS_GENERR;
</span><span class="cx"> 
</span><span class="cx">         if (data) {
</span><del>-                switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+                lock_member(member);
</ins><span class="cx">                 member-&gt;energy_level = atoi((char *) data);
</span><del>-                switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+                unlock_member(member);
</ins><span class="cx">         }
</span><span class="cx">         if (stream != NULL) {
</span><span class="cx">                 stream-&gt;write_function(stream, &quot;Energy %u = %d\n&quot;, member-&gt;id, member-&gt;energy_level);
</span><span class="lines">@@ -3285,10 +3305,10 @@
</span><span class="cx">                 return SWITCH_STATUS_GENERR;
</span><span class="cx"> 
</span><span class="cx">         if (data) {
</span><del>-                switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+                lock_member(member);
</ins><span class="cx">                 member-&gt;volume_in_level = atoi((char *) data);
</span><span class="cx">                 switch_normalize_volume(member-&gt;volume_in_level);
</span><del>-                switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+                unlock_member(member);
</ins><span class="cx">         }
</span><span class="cx">         if (stream != NULL) {
</span><span class="cx">                 stream-&gt;write_function(stream, &quot;Volume IN %u = %d\n&quot;, member-&gt;id, member-&gt;volume_in_level);
</span><span class="lines">@@ -3312,10 +3332,10 @@
</span><span class="cx">                 return SWITCH_STATUS_GENERR;
</span><span class="cx"> 
</span><span class="cx">         if (data) {
</span><del>-                switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+                lock_member(member);
</ins><span class="cx">                 member-&gt;volume_out_level = atoi((char *) data);
</span><span class="cx">                 switch_normalize_volume(member-&gt;volume_out_level);
</span><del>-                switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+                unlock_member(member);
</ins><span class="cx">         }
</span><span class="cx">         if (stream != NULL) {
</span><span class="cx">                 stream-&gt;write_function(stream, &quot;Volume OUT %u = %d\n&quot;, member-&gt;id, member-&gt;volume_out_level);
</span><span class="lines">@@ -3986,7 +4006,8 @@
</span><span class="cx">                         }
</span><span class="cx"> 
</span><span class="cx">                         /* move the member from the old conference to the new one */
</span><del>-                        switch_mutex_lock(member-&gt;control_mutex);
</del><ins>+                        lock_member(member);
+
</ins><span class="cx">                         if (conference != new_conference) {
</span><span class="cx">                                 conference_del_member(conference, member);
</span><span class="cx">                                 conference_add_member(new_conference, member);
</span><span class="lines">@@ -4001,7 +4022,7 @@
</span><span class="cx">                                 }
</span><span class="cx">                         }
</span><span class="cx"> 
</span><del>-                        switch_mutex_unlock(member-&gt;control_mutex);
</del><ins>+                        unlock_member(member);
</ins><span class="cx">                         
</span><span class="cx">                         stream-&gt;write_function(stream, &quot;OK Member '%d' sent to conference %s.\n&quot;, member-&gt;id, argv[2]);
</span><span class="cx"> 
</span><span class="lines">@@ -5252,7 +5273,8 @@
</span><span class="cx">         /* Prepare MUTEXS */
</span><span class="cx">         member.id = next_member_id();
</span><span class="cx">         switch_mutex_init(&amp;member.flag_mutex, SWITCH_MUTEX_NESTED, member.pool);
</span><del>-        switch_mutex_init(&amp;member.control_mutex, SWITCH_MUTEX_NESTED, member.pool);
</del><ins>+        switch_mutex_init(&amp;member.write_mutex, SWITCH_MUTEX_NESTED, member.pool);
+        switch_mutex_init(&amp;member.read_mutex, SWITCH_MUTEX_NESTED, member.pool);
</ins><span class="cx">         switch_mutex_init(&amp;member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool);
</span><span class="cx">         switch_mutex_init(&amp;member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>