<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>