From 851141c131ac9ab08e1420cd29f7f2f098b09e7c Mon Sep 17 00:00:00 2001 From: Richard Mudgett <rmudgett@digium.com> Date: Tue, 21 Sep 2010 20:33:20 +0000 Subject: [PATCH] Merged revisions 288079-288080 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r288079 | rmudgett | 2010-09-21 15:29:51 -0500 (Tue, 21 Sep 2010) | 2 lines Protect channel access in CONNECTED_LINE and REDIRECTING interception macro launch code. ........ r288080 | rmudgett | 2010-09-21 15:29:59 -0500 (Tue, 21 Sep 2010) | 8 lines Simplify locking code for REDIRECTING interception macro when forwarding a call. Simplified the locking code by using a local copy of the redirecting party information in app_dial.c:do_forward() and app_queue.c:wait_for_answer() for launching the REDIRECTING interception macro when a call is forwarded. Reduced the lock time of the 'o->chan' and 'in' channels. ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@288081 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_dial.c | 16 ++++++++-------- apps/app_queue.c | 17 ++++++++--------- main/channel.c | 10 ++++++++-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/apps/app_dial.c b/apps/app_dial.c index 0f7b4880d0..51dacb6db9 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -852,6 +852,8 @@ static void do_forward(struct chanlist *o, handle_cause(cause, num); ast_hangup(original); } else { + struct ast_party_redirecting redirecting; + if (single && CAN_EARLY_BRIDGE(peerflags, c, in)) { ast_rtp_instance_early_bridge_make_compatible(c, in); } @@ -895,22 +897,20 @@ static void do_forward(struct chanlist *o, * deadlock. This is why the handling of c's lock may seem a bit unusual * here. */ + ast_party_redirecting_init(&redirecting); + ast_party_redirecting_copy(&redirecting, &c->redirecting); ast_channel_unlock(c); - if (ast_channel_redirecting_macro(c, in, &c->redirecting, 1, 0)) { - while (ast_channel_trylock(c)) { - CHANNEL_DEADLOCK_AVOIDANCE(in); - } - ast_channel_update_redirecting(in, &c->redirecting, NULL); - ast_channel_unlock(c); + if (ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) { + ast_channel_update_redirecting(in, &redirecting, NULL); } + ast_party_redirecting_free(&redirecting); + ast_channel_unlock(in); ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE); if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) { *to = -1; } - ast_channel_unlock(in); - if (ast_call(c, stuff, 0)) { ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n", tech, stuff); diff --git a/apps/app_queue.c b/apps/app_queue.c index f44f2152a6..e6ce9495b5 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -3414,6 +3414,8 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte o->stillgoing = 0; numnochan++; } else { + struct ast_party_redirecting redirecting; + ast_channel_lock(o->chan); while (ast_channel_trylock(in)) { CHANNEL_DEADLOCK_AVOIDANCE(o->chan); @@ -3449,27 +3451,24 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte * deadlock. This is why the handling of o->chan's lock may * seem a bit unusual here. */ + ast_party_redirecting_init(&redirecting); + ast_party_redirecting_copy(&redirecting, &o->chan->redirecting); ast_channel_unlock(o->chan); - res = ast_channel_redirecting_macro(o->chan, in, &o->chan->redirecting, 1, 0); - while (ast_channel_trylock(o->chan)) { - CHANNEL_DEADLOCK_AVOIDANCE(in); - } + res = ast_channel_redirecting_macro(o->chan, in, &redirecting, 1, 0); if (res) { - ast_channel_update_redirecting(in, &o->chan->redirecting, NULL); + ast_channel_update_redirecting(in, &redirecting, NULL); } + ast_party_redirecting_free(&redirecting); + ast_channel_unlock(in); update_connectedline = 1; if (ast_call(o->chan, stuff, 0)) { ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n", tech, stuff); - ast_channel_unlock(o->chan); do_hang(o); numnochan++; - } else { - ast_channel_unlock(o->chan); } - ast_channel_unlock(in); } /* Hangup the original channel now, in case we needed it */ ast_hangup(winner); diff --git a/main/channel.c b/main/channel.c index 29066ebf83..880220e911 100644 --- a/main/channel.c +++ b/main/channel.c @@ -8775,9 +8775,9 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); macro_args = ast_strdupa(S_OR(macro_args, "")); - ast_channel_unlock(macro_chan); if (ast_strlen_zero(macro)) { + ast_channel_unlock(macro_chan); return -1; } @@ -8790,9 +8790,12 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc ast_party_connected_line_copy(¯o_chan->connected, connected); } + ast_channel_unlock(macro_chan); if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { + ast_channel_lock(macro_chan); ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); + ast_channel_unlock(macro_chan); } return retval; @@ -8811,9 +8814,9 @@ int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct a macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); macro_args = ast_strdupa(S_OR(macro_args, "")); - ast_channel_unlock(macro_chan); if (ast_strlen_zero(macro)) { + ast_channel_unlock(macro_chan); return -1; } @@ -8826,10 +8829,13 @@ int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct a ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); } + ast_channel_unlock(macro_chan); retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); if (!retval) { + ast_channel_lock(macro_chan); ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); + ast_channel_unlock(macro_chan); } return retval; -- GitLab