<p>Kevin Harwell <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18597">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_iax2: Prevent deadlock due to duplicate autoservice.<br><br>If a switch is invoked using chan_iax2, deadlock can result<br>because the PBX core is autoservicing the channel while chan_iax2<br>also then attempts to service it while waiting for the result<br>of the switch. This removes servicing of the channel to prevent<br>any conflicts.<br><br>ASTERISK-30064 #close<br><br>Change-Id: Ie92f206d32f9a36924af734ddde652b21106af22<br>---<br>M channels/chan_iax2.c<br>1 file changed, 20 insertions(+), 28 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c</span><br><span>index 598e9d5..2d1beb9 100644</span><br><span>--- a/channels/chan_iax2.c</span><br><span>+++ b/channels/chan_iax2.c</span><br><span>@@ -14219,9 +14219,7 @@</span><br><span> {</span><br><span>    struct iax2_dpcache *dp = NULL;</span><br><span>      struct timeval now = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">-       int x, com[2], timeout, old = 0, outfd, doabort, callno;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ast_channel *c = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ast_frame *f = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   int x, com[2], timeout, doabort, callno;</span><br><span> </span><br><span>         AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {</span><br><span>                 if (ast_tvcmp(now, dp->expiry) > 0) {</span><br><span>@@ -14268,8 +14266,8 @@</span><br><span> </span><br><span>    /* By here we must have a dp */</span><br><span>      if (dp->flags & CACHE_FLAG_PENDING) {</span><br><span style="color: hsl(0, 100%, 40%);">-            struct timeval start;</span><br><span style="color: hsl(0, 100%, 40%);">-           int ms;</span><br><span style="color: hsl(120, 100%, 40%);">+               int res;</span><br><span style="color: hsl(120, 100%, 40%);">+              struct pollfd pfd;</span><br><span>           /* Okay, here it starts to get nasty.  We need a pipe now to wait</span><br><span>               for a reply to come back so long as it's pending */</span><br><span>           for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {</span><br><span>@@ -14290,35 +14288,31 @@</span><br><span>             timeout = iaxdefaulttimeout * 1000;</span><br><span>          /* Temporarily unlock */</span><br><span>             AST_LIST_UNLOCK(&dpcache);</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Defer any dtmf */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (chan)</span><br><span style="color: hsl(0, 100%, 40%);">-                       old = ast_channel_defer_dtmf(chan);</span><br><span>          doabort = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-            start = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">-            while ((ms = ast_remaining_ms(start, timeout))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (outfd > -1)</span><br><span style="color: hsl(0, 100%, 40%);">-                              break;</span><br><span style="color: hsl(0, 100%, 40%);">-                  if (!c)</span><br><span style="color: hsl(0, 100%, 40%);">-                         continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!(f = ast_read(c))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               doabort = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                            break;</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_frfree(f);</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!ms) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* chan is in autoservice here, so do NOT service it here! */</span><br><span style="color: hsl(120, 100%, 40%);">+         pfd.fd = com[0];</span><br><span style="color: hsl(120, 100%, 40%);">+              pfd.events = POLLIN;</span><br><span style="color: hsl(120, 100%, 40%);">+          pfd.revents = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */</span><br><span style="color: hsl(120, 100%, 40%);">+           res = ast_poll(&pfd, 1, timeout);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (res < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else if (!pfd.revents) {</span><br><span>                   ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);</span><br><span>            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ast_check_hangup(chan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 doabort = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          AST_LIST_LOCK(&dpcache);</span><br><span>                 dp->waiters[x] = -1;</span><br><span>              close(com[1]);</span><br><span>               close(com[0]);</span><br><span>               if (doabort) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  /* Don't interpret anything, just abort.  Not sure what th epoint</span><br><span style="color: hsl(0, 100%, 40%);">-                     of undeferring dtmf on a hung up channel is but hey whatever */</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!old && chan)</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_channel_undefer_dtmf(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* Don't interpret anything, just abort. */</span><br><span>                      return NULL;</span><br><span>                 }</span><br><span>            if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {</span><br><span>@@ -14341,8 +14335,6 @@</span><br><span>                    }</span><br><span>            }</span><br><span>            /* Our caller will obtain the rest */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!old && chan)</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_channel_undefer_dtmf(chan);</span><br><span>      }</span><br><span>    return dp;</span><br><span> }</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18597">change 18597</a>. To unsubscribe, or for help writing mail filters, 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/c/asterisk/+/18597"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: Ie92f206d32f9a36924af734ddde652b21106af22 </div>
<div style="display:none"> Gerrit-Change-Number: 18597 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>