[asterisk-commits] rmudgett: branch 10 r344540 - in /branches/10: ./ apps/app_queue.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Nov 10 17:01:36 CST 2011


Author: rmudgett
Date: Thu Nov 10 17:01:31 2011
New Revision: 344540

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=344540
Log:
Fix potential deadlock calling ast_call() with channel locks held.

Fixed app_queue.c:ring_entry() calling ast_call() with the channel locks
held.  Chan_local attempts to do deadlock avoidance in its ast_call()
callback and could deadlock if a channel lock is already held.
........

Merged revisions 344539 from http://svn.asterisk.org/svn/asterisk/branches/1.8

Modified:
    branches/10/   (props changed)
    branches/10/apps/app_queue.c

Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/10/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/apps/app_queue.c?view=diff&rev=344540&r1=344539&r2=344540
==============================================================================
--- branches/10/apps/app_queue.c (original)
+++ branches/10/apps/app_queue.c Thu Nov 10 17:01:31 2011
@@ -3119,10 +3119,7 @@
 		return 0;
 	}
 
-	ast_channel_lock(tmp->chan);
-	while (ast_channel_trylock(qe->chan)) {
-		CHANNEL_DEADLOCK_AVOIDANCE(tmp->chan);
-	}
+	ast_channel_lock_both(tmp->chan, qe->chan);
 
 	if (qe->cancel_answered_elsewhere) {
 		ast_set_flag(tmp->chan, AST_FLAG_ANSWERED_ELSEWHERE);
@@ -3185,19 +3182,22 @@
 		strcpy(tmp->chan->cdr->userfield, qe->chan->cdr->userfield);
 	}
 
+	ast_channel_unlock(tmp->chan);
+	ast_channel_unlock(qe->chan);
+
 	/* Place the call, but don't wait on the answer */
 	if ((res = ast_call(tmp->chan, location, 0))) {
 		/* Again, keep going even if there's an error */
 		ast_debug(1, "ast call on peer returned %d\n", res);
 		ast_verb(3, "Couldn't call %s\n", tmp->interface);
-		ast_channel_unlock(tmp->chan);
-		ast_channel_unlock(qe->chan);
 		do_hang(tmp);
 		(*busies)++;
 		update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
 		return 0;
 	} else if (qe->parent->eventwhencalled) {
 		char vars[2048];
+
+		ast_channel_lock_both(tmp->chan, qe->chan);
 
 		manager_event(EVENT_FLAG_AGENT, "AgentCalled",
 			"Queue: %s\r\n"
@@ -3221,10 +3221,12 @@
 			S_COR(qe->chan->connected.id.name.valid, qe->chan->connected.id.name.str, "unknown"),
 			qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
 			qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
+
+		ast_channel_unlock(tmp->chan);
+		ast_channel_unlock(qe->chan);
+
 		ast_verb(3, "Called %s\n", tmp->interface);
 	}
-	ast_channel_unlock(tmp->chan);
-	ast_channel_unlock(qe->chan);
 
 	update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
 	return 1;
@@ -3658,10 +3660,7 @@
 					} else {
 						struct ast_party_redirecting redirecting;
 
-						ast_channel_lock(o->chan);
-						while (ast_channel_trylock(in)) {
-							CHANNEL_DEADLOCK_AVOIDANCE(o->chan);
-						}
+						ast_channel_lock_both(o->chan, in);
 						ast_channel_inherit_variables(in, o->chan);
 						ast_channel_datastore_inherit(in, o->chan);
 




More information about the asterisk-commits mailing list