mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	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
This commit is contained in:
		@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user