[Asterisk-code-review] chan_iax2: Prevent deadlock due to duplicate autoservice. (asterisk[16])
N A
asteriskteam at digium.com
Thu Jun 2 12:21:56 CDT 2022
N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18597 )
Change subject: chan_iax2: Prevent deadlock due to duplicate autoservice.
......................................................................
chan_iax2: Prevent deadlock due to duplicate autoservice.
If a switch is invoked using chan_iax2, deadlock can result
because the PBX core is autoservicing the channel while chan_iax2
also then attempts to service it while waiting for the result
of the switch. This removes servicing of the channel to prevent
any conflicts.
ASTERISK-30064 #close
Change-Id: Ie92f206d32f9a36924af734ddde652b21106af22
---
M channels/chan_iax2.c
1 file changed, 20 insertions(+), 28 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/97/18597/1
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 598e9d5..2d1beb9 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -14219,9 +14219,7 @@
{
struct iax2_dpcache *dp = NULL;
struct timeval now = ast_tvnow();
- int x, com[2], timeout, old = 0, outfd, doabort, callno;
- struct ast_channel *c = NULL;
- struct ast_frame *f = NULL;
+ int x, com[2], timeout, doabort, callno;
AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
if (ast_tvcmp(now, dp->expiry) > 0) {
@@ -14268,8 +14266,8 @@
/* By here we must have a dp */
if (dp->flags & CACHE_FLAG_PENDING) {
- struct timeval start;
- int ms;
+ int res;
+ struct pollfd pfd;
/* Okay, here it starts to get nasty. We need a pipe now to wait
for a reply to come back so long as it's pending */
for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
@@ -14290,35 +14288,31 @@
timeout = iaxdefaulttimeout * 1000;
/* Temporarily unlock */
AST_LIST_UNLOCK(&dpcache);
- /* Defer any dtmf */
- if (chan)
- old = ast_channel_defer_dtmf(chan);
doabort = 0;
- start = ast_tvnow();
- while ((ms = ast_remaining_ms(start, timeout))) {
- c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
- if (outfd > -1)
- break;
- if (!c)
- continue;
- if (!(f = ast_read(c))) {
- doabort = 1;
- break;
- }
- ast_frfree(f);
- }
- if (!ms) {
+
+ /* chan is in autoservice here, so do NOT service it here! */
+ pfd.fd = com[0];
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */
+ res = ast_poll(&pfd, 1, timeout);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
+ return NULL;
+ } else if (!pfd.revents) {
ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
}
+
+ if (ast_check_hangup(chan)) {
+ doabort = 1;
+ }
+
AST_LIST_LOCK(&dpcache);
dp->waiters[x] = -1;
close(com[1]);
close(com[0]);
if (doabort) {
- /* Don't interpret anything, just abort. Not sure what th epoint
- of undeferring dtmf on a hung up channel is but hey whatever */
- if (!old && chan)
- ast_channel_undefer_dtmf(chan);
+ /* Don't interpret anything, just abort. */
return NULL;
}
if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
@@ -14341,8 +14335,6 @@
}
}
/* Our caller will obtain the rest */
- if (!old && chan)
- ast_channel_undefer_dtmf(chan);
}
return dp;
}
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18597
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-Change-Id: Ie92f206d32f9a36924af734ddde652b21106af22
Gerrit-Change-Number: 18597
Gerrit-PatchSet: 1
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220602/247080aa/attachment.html>
More information about the asterisk-code-review
mailing list