diff options
author | Russell Bryant <russell@russellbryant.com> | 2011-04-26 17:41:51 +0000 |
---|---|---|
committer | Russell Bryant <russell@russellbryant.com> | 2011-04-26 17:41:51 +0000 |
commit | 83ad7a9e6c06d09690e86e94d59044b601188d3c (patch) | |
tree | 5562389873895eed2135876ede3d586762e6f343 /channels | |
parent | 92358b078c18c53182749b6b98cce41bd05376ff (diff) |
Merged revisions 315446 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r315446 | russell | 2011-04-26 12:40:23 -0500 (Tue, 26 Apr 2011) | 14 lines
chan_local: resolve a deadlock.
This patch resolves a fairly complex deadlock that can occur with the
combination of chan_local and a dialplan switch, such as dynamic realtime
extensions, which pulls autoservice into the picture when doing a dialplan
lookup.
(closes issue #18818)
Reported by: nic
Patches:
issue18818.patch uploaded by jthurman (license 614)
18818.v1.txt uploaded by russell (license 2)
Tested by: nic, jthurman, kterzi, steve-howes, sysreq, IshMalik
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@315447 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_local.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index d28c0d306..f590bf33a 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -736,6 +736,9 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout) size_t len, namelen; char *reduced_dest = ast_strdupa(dest); char *slash; + struct ast_channel *chan; + const char *exten; + const char *context; if (!p || p->owner != ast) { return -1; @@ -820,21 +823,28 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout) } ast_set_cc_interfaces_chanvar(p->chan, reduced_dest); - if (!ast_exists_extension(p->chan, p->chan->context, p->chan->exten, 1, + chan = ast_channel_ref(p->chan); + ao2_unlock(p); + exten = ast_strdupa(chan->exten); + context = ast_strdupa(chan->context); + ast_channel_unlock(chan); + + if (!ast_exists_extension(chan, context, exten, 1, S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { - ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", p->chan->exten, p->chan->context); - ao2_unlock(p); - ast_channel_unlock(p->chan); - ao2_ref(p, -1); - return -1; + ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context); + res = -1; + goto return_cleanup; } /* Start switch on sub channel */ - if (!(res = ast_pbx_start(p->chan))) + if (!(res = ast_pbx_start(chan))) { + ao2_lock(p); ast_set_flag(p, LOCAL_LAUNCHED_PBX); + ao2_unlock(p); + } - ao2_unlock(p); - ast_channel_unlock(p->chan); +return_cleanup: + ast_channel_unref(chan); ao2_ref(p, -1); return res; } |