[svn-commits] murf: branch murf/mtxprof r125137 - in /team/murf/mtxprof: channels/ funcs/ i...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jun 25 17:46:23 CDT 2008


Author: murf
Date: Wed Jun 25 17:46:22 2008
New Revision: 125137

URL: http://svn.digium.com/view/asterisk?view=rev&rev=125137
Log:
OK, A LOT of debug added to try and understand why the lock in __ast_answer() is taking so long to get. Unfortunately, it's because call to ast_pbx_start() in the handle_request_invite() func takes an avg of 50 million cpu ticks to complete. By the time it returns, the new thread has already started, and __ast_answer is waiting for its parent to release the channel lock. The amount of time that ast_pbx_start() takes would seem to me a limiting factor in how many calls/sec the sip channel driver can accept. If you don't want to see all the ast_log calls concerning locks, then remove them from the macros in lock.h at lines 1714-1723. A lot of blood, sweat, and tears went into showing all the lock calls.

Modified:
    team/murf/mtxprof/channels/chan_agent.c
    team/murf/mtxprof/channels/chan_dahdi.c
    team/murf/mtxprof/channels/chan_iax2.c
    team/murf/mtxprof/channels/chan_local.c
    team/murf/mtxprof/channels/chan_mgcp.c
    team/murf/mtxprof/channels/chan_sip.c
    team/murf/mtxprof/channels/console_video.c
    team/murf/mtxprof/funcs/func_channel.c
    team/murf/mtxprof/funcs/func_global.c
    team/murf/mtxprof/include/asterisk/lock.h
    team/murf/mtxprof/main/channel.c
    team/murf/mtxprof/main/features.c
    team/murf/mtxprof/main/pbx.c
    team/murf/mtxprof/main/rtp.c
    team/murf/mtxprof/main/udptl.c
    team/murf/mtxprof/main/utils.c
    team/murf/mtxprof/res/res_agi.c
    team/murf/mtxprof/res/res_monitor.c

Modified: team/murf/mtxprof/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_agent.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_agent.c (original)
+++ team/murf/mtxprof/channels/chan_agent.c Wed Jun 25 17:46:22 2008
@@ -1529,7 +1529,10 @@
 				if (!soft) {
 					ast_mutex_lock(&p->lock);
 
-					while (p->owner && ast_channel_trylock(p->owner)) {
+					while (p->owner) {
+						int ret;
+						ast_channel_trylock_assign(p->owner,ret);
+						if (!ret) break;
 						DEADLOCK_AVOIDANCE(&p->lock);
 					}
 					if (p->owner) {
@@ -1537,7 +1540,10 @@
 						ast_channel_unlock(p->owner);
 					}
 
-					while (p->chan && ast_channel_trylock(p->chan)) {
+					while (p->chan) {
+						int ret;
+						ast_channel_trylock_assign(p->owner,ret);
+						if (!ret) break;
 						DEADLOCK_AVOIDANCE(&p->lock);
 					}
 					if (p->chan) {

Modified: team/murf/mtxprof/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_dahdi.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_dahdi.c (original)
+++ team/murf/mtxprof/channels/chan_dahdi.c Wed Jun 25 17:46:22 2008
@@ -966,7 +966,9 @@
 #endif			
 	for (;;) {
 		if (p->subs[a].owner) {
-			if (ast_channel_trylock(p->subs[a].owner)) {
+			int ret;
+			ast_channel_trylock_assign(p->subs[a].owner,ret);
+			if (ret) {
 				DEADLOCK_AVOIDANCE(&p->lock);
 			} else {
 				ast_queue_frame(p->subs[a].owner, &ast_null_frame);
@@ -1013,7 +1015,9 @@
 #endif		
 	for (;;) {
 		if (p->owner) {
-			if (ast_channel_trylock(p->owner)) {
+			int ret;
+			ast_channel_trylock_assign(p->owner,ret);
+			if (ret) {
 				DEADLOCK_AVOIDANCE(&p->lock);
 			} else {
 				ast_queue_frame(p->owner, f);
@@ -3728,6 +3732,7 @@
 	struct dahdi_pvt *p0, *p1, *op0, *op1;
 	struct dahdi_pvt *master = NULL, *slave = NULL;
 	struct ast_frame *f;
+	int ret;
 	int inconf = 0;
 	int nothingok = 1;
 	int ofd0, ofd1;
@@ -3751,8 +3756,10 @@
 		return AST_BRIDGE_FAILED_NOWARN;
 
 	ast_channel_lock(c0);
-	while (ast_channel_trylock(c1)) {
+	ast_channel_trylock_assign(c1,ret);
+	while (ret) {
 		CHANNEL_DEADLOCK_AVOIDANCE(c0);
+		ast_channel_trylock_assign(c1,ret);
 	}
 
 	p0 = c0->tech_pvt;
@@ -3921,8 +3928,10 @@
 		   and then balking if anything is wrong */
 		
 		ast_channel_lock(c0);
-		while (ast_channel_trylock(c1)) {
+		ast_channel_trylock_assign(c1,ret);
+		while (ret) {
 			CHANNEL_DEADLOCK_AVOIDANCE(c0);
+			ast_channel_trylock_assign(c1,ret);
 		}
 
 		p0 = c0->tech_pvt;
@@ -4458,9 +4467,11 @@
 						dahdi_ring_phone(p);
 					} else if (p->subs[SUB_THREEWAY].owner) {
 						unsigned int mssinceflash;
+						int lockret;
 						/* Here we have to retain the lock on both the main channel, the 3-way channel, and
 						   the private structure -- not especially easy or clean */
-						while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
+						ast_channel_trylock_assign(p->subs[SUB_THREEWAY].owner,lockret);
+						while (p->subs[SUB_THREEWAY].owner && lockret) {
 							/* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
 							DLA_UNLOCK(&p->lock);
 							CHANNEL_DEADLOCK_AVOIDANCE(ast);
@@ -4472,6 +4483,7 @@
 								ast_log(LOG_WARNING, "This isn't good...\n");
 								return NULL;
 							}
+							ast_channel_trylock_assign(p->subs[SUB_THREEWAY].owner,lockret);
 						}
 						if (!p->subs[SUB_THREEWAY].owner) {
 							ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
@@ -4503,19 +4515,22 @@
 								} else {
 									if ((res = attempt_transfer(p)) < 0) {
 										p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
-										if (p->subs[SUB_THREEWAY].owner)
+										if (p->subs[SUB_THREEWAY].owner) {
 											ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
+										}
 									} else if (res) {
 										/* Don't actually hang up at this point */
-										if (p->subs[SUB_THREEWAY].owner)
+										if (p->subs[SUB_THREEWAY].owner) {
 											ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
+										}
 										break;
 									}
 								}
 							} else {
 								p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
-								if (p->subs[SUB_THREEWAY].owner)
+								if (p->subs[SUB_THREEWAY].owner) {
 									ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
+								}
 							}
 						} else {
 							ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
@@ -10258,9 +10273,14 @@
 	do {
 		redo = 0;
 		for (x = 0; x < 3; x++) {
-			while (p->subs[x].owner && ast_channel_trylock(p->subs[x].owner)) {
+			int lockret;
+			if (!p->subs[x].owner)
+				continue;
+			ast_channel_trylock_assign(p->subs[x].owner,lockret);
+			while (p->subs[x].owner && lockret) {
 				redo++;
 				DEADLOCK_AVOIDANCE(&p->lock);
+				ast_channel_trylock_assign(p->subs[x].owner,lockret);
 			}
 			if (p->subs[x].owner) {
 				ast_queue_hangup_with_cause(p->subs[x].owner, AST_CAUSE_PRE_EMPTED);

Modified: team/murf/mtxprof/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_iax2.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_iax2.c (original)
+++ team/murf/mtxprof/channels/chan_iax2.c Wed Jun 25 17:46:22 2008
@@ -1772,7 +1772,9 @@
 {
 	for (;;) {
 		if (iaxs[callno] && iaxs[callno]->owner) {
-			if (ast_channel_trylock(iaxs[callno]->owner)) {
+			int lockret;
+			ast_channel_trylock_assign(iaxs[callno]->owner,lockret);
+			if (lockret) {
 				/* Avoid deadlock by pausing and trying again */
 				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			} else {
@@ -1803,7 +1805,9 @@
 {
 	for (;;) {
 		if (iaxs[callno] && iaxs[callno]->owner) {
-			if (ast_channel_trylock(iaxs[callno]->owner)) {
+			int lockret;
+			ast_channel_trylock_assign(iaxs[callno]->owner,lockret);
+			if (lockret) {
 				/* Avoid deadlock by pausing and trying again */
 				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			} else {
@@ -1835,7 +1839,9 @@
 {
 	for (;;) {
 		if (iaxs[callno] && iaxs[callno]->owner) {
-			if (ast_channel_trylock(iaxs[callno]->owner)) {
+			int lockret;
+			ast_channel_trylock_assign(iaxs[callno]->owner,lockret);
+			if (lockret) {
 				/* Avoid deadlock by pausing and trying again */
 				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			} else {
@@ -2246,7 +2252,9 @@
 	owner = pvt ? pvt->owner : NULL;
 
 	if (owner) {
-		if (ast_channel_trylock(owner)) {
+		int lockret;
+		ast_channel_trylock_assign(owner,lockret);
+		if (lockret) {
 			ast_debug(3, "Avoiding IAX destroy deadlock\n");
 			DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			goto retry;
@@ -8299,8 +8307,10 @@
 					ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
 					if (iaxs[fr->callno]->owner) {
 						int orignative;
+						int lockret;
 retryowner:
-						if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
+						ast_channel_trylock_assign(iaxs[fr->callno]->owner,lockret);
+						if (lockret) {
 							DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
 							if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
 						}
@@ -8738,11 +8748,13 @@
 				} else {
 					ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 					if (iaxs[fr->callno]->owner) {
+						int lockret;
 						/* Switch us to use a compatible format */
 						iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
 						ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
 retryowner2:
-						if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
+						ast_channel_trylock_assign(iaxs[fr->callno]->owner,lockret);
+						if (lockret) {
 							DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
 							if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
 						}

Modified: team/murf/mtxprof/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_local.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_local.c (original)
+++ team/murf/mtxprof/channels/chan_local.c Wed Jun 25 17:46:22 2008
@@ -199,7 +199,8 @@
 	struct ast_channel *us, int us_locked)
 {
 	struct ast_channel *other = NULL;
-
+	int lockret;
+	
 	/* Recalculate outbound channel */
 	other = isoutbound ? p->owner : p->chan;
 
@@ -218,7 +219,8 @@
 	}
 
 	/* Ensure that we have both channels locked */
-	while (other && ast_channel_trylock(other)) {
+	ast_channel_trylock_assign(other,lockret);
+	while (other && lockret) {
 		DLA_UNLOCK(&p->lock);
 		if (us && us_locked) {
 			CHANNEL_DEADLOCK_AVOIDANCE(us);
@@ -227,6 +229,7 @@
 		}
 		DLA_LOCK(&p->lock);
 		other = isoutbound ? p->owner : p->chan;
+		ast_channel_trylock_assign(other,lockret);
 	}
 
 	if (other) {
@@ -273,13 +276,16 @@
 	   outbound channel during the masquerade)
 	*/
 	if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
+		int lockret;
 		/* Masquerade bridged channel into owner */
 		/* Lock everything we need, one by one, and give up if
 		   we can't get everything.  Remember, we'll get another
 		   chance in just a little bit */
-		if (!ast_channel_trylock(p->chan->_bridge)) {
+		ast_channel_trylock_assign(p->chan->_bridge,lockret);
+		if (!lockret) {
 			if (!ast_check_hangup(p->chan->_bridge)) {
-				if (!ast_channel_trylock(p->owner)) {
+				ast_channel_trylock_assign(p->owner,lockret);
+				if (!lockret) {
 					if (!ast_check_hangup(p->owner)) {
 						if(p->owner->monitor && !p->chan->_bridge->monitor) {
 							/* If a local channel is being monitored, we don't want a masquerade
@@ -549,8 +555,10 @@
 	if (isoutbound) {
 		const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
 		if ((status) && (p->owner)) {
+			int lockret;
 			/* Deadlock avoidance */
-			while (p->owner && ast_channel_trylock(p->owner)) {
+			ast_channel_trylock_assign(p->owner,lockret);
+			while (p->owner && lockret) {
 				ast_mutex_unlock(&p->lock);
 				if (ast) {
 					ast_channel_unlock(ast);
@@ -560,6 +568,7 @@
 					ast_channel_lock(ast);
 				}
 				ast_mutex_lock(&p->lock);
+				ast_channel_trylock_assign(p->owner,lockret);
 			}
 			if (p->owner) {
 				pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);

Modified: team/murf/mtxprof/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_mgcp.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_mgcp.c (original)
+++ team/murf/mtxprof/channels/chan_mgcp.c Wed Jun 25 17:46:22 2008
@@ -591,7 +591,9 @@
 {
 	for(;;) {
 		if (sub->owner) {
-			if (!ast_channel_trylock(sub->owner)) {
+			int lockret;
+			ast_channel_trylock_assign(sub->owner,lockret);
+			if (!lockret) {
 				ast_queue_frame(sub->owner, f);
 				ast_channel_unlock(sub->owner);
 				break;
@@ -607,7 +609,9 @@
 {
 	for(;;) {
 		if (sub->owner) {
-			if (!ast_channel_trylock(sub->owner)) {
+			int lockret;
+			ast_channel_trylock_assign(sub->owner,lockret);
+			if (!lockret) {
 				ast_queue_hangup(sub->owner);
 				ast_channel_unlock(sub->owner);
 				break;

Modified: team/murf/mtxprof/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/chan_sip.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/chan_sip.c (original)
+++ team/murf/mtxprof/channels/chan_sip.c Wed Jun 25 17:46:22 2008
@@ -2449,12 +2449,14 @@
 
 	/* Unlink us from the owner (channel) if we have one */
 	if (dialog->owner) {
-		if (lockowner)
+		if (lockowner) {
 			ast_channel_lock(dialog->owner);
+		}
 		ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
 		dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
-		if (lockowner)
+		if (lockowner) {
 			ast_channel_unlock(dialog->owner);
+		}
 	}
 	if (dialog->registry) {
 		if (dialog->registry->call == dialog)
@@ -2959,12 +2961,18 @@
 	pkt->retransid = -1;
 
 	if (pkt->is_fatal) {
-		while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
-			sip_pvt_unlock(pkt->owner);	/* SIP_PVT, not channel */
-			usleep(1);
-			sip_pvt_lock(pkt->owner);
-		}
-
+		int lockret;
+		if (pkt->owner->owner)
+		{
+			ast_channel_trylock_assign(pkt->owner->owner,lockret);
+			while(pkt->owner->owner && lockret) {
+				sip_pvt_unlock(pkt->owner);	/* SIP_PVT, not channel */
+				usleep(1);
+				sip_pvt_lock(pkt->owner);
+				ast_channel_trylock_assign(pkt->owner->owner,lockret);
+			}
+		}
+		
 		if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 
 			pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
 		
@@ -2987,8 +2995,9 @@
 
 	if (pkt->method == SIP_BYE) {
 		/* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
-		if (pkt->owner->owner) 
+		if (pkt->owner->owner){
 			ast_channel_unlock(pkt->owner->owner);
+		}
 		append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
 		pkt->owner->needdestroy = 1;
 	}
@@ -4424,8 +4433,10 @@
 	sip_pvt_lock(p);
 	p->initid = -1;	/* event gone, will not be rescheduled */
 	if (p->owner) {
+		int lockret;
 		/* XXX fails on possible deadlock */
-		if (!ast_channel_trylock(p->owner)) {
+		ast_channel_trylock_assign(p->owner,lockret);
+		if (!lockret) {
 			append_history(p, "Cong", "Auto-congesting (timer)");
 			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
 			ast_channel_unlock(p->owner);
@@ -4568,15 +4579,17 @@
 
 	/* Unlink us from the owner if we have one */
 	if (p->owner) {
-		if (lockowner)
+		if (lockowner) {
 			ast_channel_lock(p->owner);
+		}
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
 		p->owner->tech_pvt = NULL;
 		/* Make sure that the channel knows its backend is going away */
 		p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-		if (lockowner)
+		if (lockowner) {
 			ast_channel_unlock(p->owner);
+		}
 		/* Give the channel a chance to react before deallocation */
 		usleep(1);
 	}
@@ -9319,7 +9332,7 @@
 
 		while ((individual_hint = strsep(&hint2, "&"))) {
 			hint_count++;
-
+			ast_log(LOG_NOTICE,"Calling ast_device_state\n");
 			if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
 				unavailable_count++;
 		}
@@ -11274,6 +11287,7 @@
 	sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
 	if (sip_pvt_ptr) {
 		char *ourtag = sip_pvt_ptr->tag;
+		int lockret;
 		/* Go ahead and lock it (and its owner) before returning */
 		sip_pvt_lock(sip_pvt_ptr);
 		
@@ -11291,10 +11305,14 @@
 					  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
 
 		/* deadlock avoidance... */
-		while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
-			sip_pvt_unlock(sip_pvt_ptr);
-			usleep(1);
-			sip_pvt_lock(sip_pvt_ptr);
+		if (sip_pvt_ptr->owner) {
+			ast_channel_trylock_assign(sip_pvt_ptr->owner,lockret);
+			while (sip_pvt_ptr->owner && lockret) {
+				sip_pvt_unlock(sip_pvt_ptr);
+				usleep(1);
+				sip_pvt_lock(sip_pvt_ptr);
+				ast_channel_trylock_assign(sip_pvt_ptr->owner,lockret);
+			}
 		}
 	}
 	
@@ -16880,6 +16898,7 @@
 	struct ast_channel *transferee, *transferer;
 		/* Chan2m: The transferer, chan1m: The transferee */
 	pthread_t th;
+	int lockret;
 
 	transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
 	transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
@@ -16917,11 +16936,13 @@
 	/* Prepare for taking over the channel.  Go ahead and grab this channel
 	 * lock here to avoid a deadlock with callbacks into the channel driver
 	 * that hold the channel lock and want the pvt lock.  */
-	while (ast_channel_trylock(chan2)) {
+	ast_channel_trylock_assign(chan2,lockret);
+	while (lockret) {
 		struct sip_pvt *pvt = chan2->tech_pvt;
 		sip_pvt_unlock(pvt);
 		usleep(1);
 		sip_pvt_lock(pvt);
+		ast_channel_trylock_assign(chan2,lockret);
 	}
 	ast_channel_masquerade(transferer, chan2);
 	ast_channel_unlock(chan2);
@@ -17338,8 +17359,9 @@
 	ast_quiet_chan(targetcall);
 	ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
 	/* Unlock clone, but not original (replacecall) */
-	if (!oneleggedreplace)
+	if (!oneleggedreplace) {
 		ast_channel_unlock(c);
+	}
 
 	/* Unlock PVT */
 	sip_pvt_unlock(p->refer->refer_call);
@@ -17370,8 +17392,9 @@
 			ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
 		}
 		c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
-		if (!oneleggedreplace)
+		if (!oneleggedreplace) {
 			ast_channel_unlock(replacecall);
+		}
 	} else {	/* Bridged call, UP channel */
 		if ((f = ast_read(replacecall))) {	/* Force the masq to happen */
 			/* Masq ok */
@@ -17899,9 +17922,29 @@
 			p->invitestate = INV_PROCEEDING;
 			ast_setstate(c, AST_STATE_RING);
 			if (strcmp(p->exten, ast_pickup_ext())) {	/* Call to extension -start pbx on this call */
+				static int pbx_mark = -1;
 				enum ast_pbx_result res;
-
+				struct timeval start9, end9;
+				static int totaltime = 0;
+				static int numtimes = 0;
+				int timediff;
+				uint64_t st1;
+				
+				if (pbx_mark == -1) {
+					pbx_mark = ast_add_profile("pbx_start_time", 0);
+				}
+				
+				ast_log(LOG_NOTICE,"about to start PBX\n");
+				start9 = ast_tvnow();
+				st1 = ast_mark2();
 				res = ast_pbx_start(c);
+				ast_mark3(pbx_mark, st1);
+				end9 = ast_tvnow();
+				timediff = ast_tvdiff_us(end9, start9);
+				totaltime += timediff;
+				numtimes++;
+				
+				ast_log(LOG_NOTICE,"PBX is started -- took %d microseconds, avg=%d usec (%d times)\n", timediff, totaltime/numtimes, numtimes);
 
 				switch(res) {
 				case AST_PBX_FAILED:
@@ -18166,8 +18209,9 @@
 		/* Failed transfer */
 		transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
 		append_history(transferer, "Xfer", "Refer failed");
-		if (targetcall_pvt->owner)
+		if (targetcall_pvt->owner) {
 			ast_channel_unlock(targetcall_pvt->owner);
+		}
 		/* Right now, we have to hangup, sorry. Bridge is destroyed */
 		if (res != -2)
 			ast_hangup(transferer->owner);
@@ -19485,6 +19529,7 @@
 
 	/* Process request, with netlock held, and with usual deadlock avoidance */
 	for (lockretry = 100; lockretry > 0; lockretry--) {
+		int lockret;
 		ast_mutex_lock(&netlock);
 
 		/* Find the active SIP dialog or create a new one */
@@ -19499,7 +19544,10 @@
 
 		/* Go ahead and lock the owner if it has one -- we may need it */
 		/* becaues this is deadlock-prone, we need to try and unlock if failed */
-		if (!p->owner || !ast_channel_trylock(p->owner))
+		if (p->owner) {
+			ast_channel_trylock_assign(p->owner,lockret);
+		}
+		if (!p->owner || !lockret)
 			break;	/* locking succeeded */
 		ast_debug(1, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
 		sip_pvt_unlock(p);
@@ -19535,8 +19583,9 @@
 	if (recount)
 		ast_update_use_count();
 
-	if (p->owner && !nounlock)
+	if (p->owner && !nounlock) {
 		ast_channel_unlock(p->owner);
+	}
 	sip_pvt_unlock(p);
 	ast_mutex_unlock(&netlock);
 	ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
@@ -19772,10 +19821,15 @@
 		     (t > dialog->lastrtprx + ast_rtp_get_rtpholdtimeout(dialog->rtp)))) {
 			/* Needs a hangup */
 			if (ast_rtp_get_rtptimeout(dialog->rtp)) {
-				while (dialog->owner && ast_channel_trylock(dialog->owner)) {
+				int lockret;
+				if (dialog->owner) {
+					ast_channel_trylock_assign(dialog->owner,lockret);
+				}
+				while (dialog->owner && lockret) {
 					sip_pvt_unlock(dialog);
 					usleep(1);
 					sip_pvt_lock(dialog);
+					ast_channel_trylock_assign(dialog->owner,lockret);
 				}
 				ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
 					dialog->owner->name, (long) (t - dialog->lastrtprx));
@@ -19988,17 +20042,22 @@
 	} else {
 		p->stimer->st_expirys++;
 		if (p->stimer->st_expirys >= 2) {
+			int lockret;
 			ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
 			stop_session_timer(p);
 
-			while (p->owner && ast_channel_trylock(p->owner)) {
+			if (p->owner) {
+				ast_channel_trylock_assign(p->owner,lockret);
+			}
+			while (p->owner && lockret) {
 				sip_pvt_unlock(p);
 				usleep(1);
 				sip_pvt_lock(p);
-          		}
-
-           		ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
-           		ast_channel_unlock(p->owner);
+				ast_channel_trylock_assign(p->owner,lockret);
+			}
+
+			ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
+			ast_channel_unlock(p->owner);
 		}
 	}
 	return 1;

Modified: team/murf/mtxprof/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/channels/console_video.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/channels/console_video.c (original)
+++ team/murf/mtxprof/channels/console_video.c Wed Jun 25 17:46:22 2008
@@ -454,8 +454,9 @@
 				ast_channel_unlock(env->owner);
 			usleep(t);
 			t = 1000000;
-			if (env->owner)
+			if (env->owner) {
 				ast_channel_lock(env->owner);
+			}
 		}
 	}
 	env->owner = NULL;	/* this is unconditional */

Modified: team/murf/mtxprof/funcs/func_channel.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/funcs/func_channel.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/funcs/func_channel.c (original)
+++ team/murf/mtxprof/funcs/func_channel.c Wed Jun 25 17:46:22 2008
@@ -263,7 +263,7 @@
 		}
 	}
 
-	for (c = ast_channel_walk_locked(NULL); c; ast_channel_unlock(c), c = ast_channel_walk_locked(c)) {
+	for (c = ast_channel_walk_locked(NULL); c; ast_channel_unlock_comma(c), c = ast_channel_walk_locked(c)) {
 		if (ast_strlen_zero(data) || regexec(&re, c->name, 0, NULL, 0) == 0) {
 			size_t namelen = strlen(c->name);
 			if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {

Modified: team/murf/mtxprof/funcs/func_global.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/funcs/func_global.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/funcs/func_global.c (original)
+++ team/murf/mtxprof/funcs/func_global.c Wed Jun 25 17:46:22 2008
@@ -106,8 +106,9 @@
 			ast_log(LOG_ERROR, "Channel '%s' not found!  Variable '%s' will be blank.\n", args.chan, args.var);
 			return -1;
 		}
-	} else
+	} else {
 		ast_channel_lock(chan);
+	}
 
 	if (!(varstore = ast_channel_datastore_find(chan, &shared_variable_info, NULL))) {
 		ast_channel_unlock(chan);
@@ -154,8 +155,9 @@
 			ast_log(LOG_ERROR, "Channel '%s' not found!  Variable '%s' not set to '%s'.\n", args.chan, args.var, value);
 			return -1;
 		}
-	} else
+	} else {
 		ast_channel_lock(chan);
+	}
 
 	if (!(varstore = ast_channel_datastore_find(chan, &shared_variable_info, NULL))) {
 		if (!(varstore = ast_channel_datastore_alloc(&shared_variable_info, NULL))) {

Modified: team/murf/mtxprof/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/include/asterisk/lock.h?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/include/asterisk/lock.h (original)
+++ team/murf/mtxprof/include/asterisk/lock.h Wed Jun 25 17:46:22 2008
@@ -59,14 +59,14 @@
  * non-blocking calls.
  */
 #ifndef	HAVE_MTX_PROFILE
-#define	__MTX_PROF(a, file, func, lineno, start, mtx_prof)	return pthread_mutex_lock((a))
+#define	__MTX_PROF(a, file, func, lineno, start, mtx_prof, lockstr)	return pthread_mutex_lock((a))
 #else
 /* make the MTX_PROF thread-safe (localize the start time, use fetchadd to add in the wait time, and bump the event count) */
-#define	__MTX_PROF(a, file, func, lineno, start, mtx_prof)	do {	\
+#define	__MTX_PROF(a, file, func, lineno, start, mtx_prof, lockstr)	do {	\
 	int i;					    \
 	if (*(mtx_prof) == -1) {										\
 	    char nbuf[512];												\
-		snprintf(nbuf, sizeof(nbuf), "%s__%s__%d", file, func, lineno);	\
+		snprintf(nbuf, sizeof(nbuf), "%s__%s__%d__%s", file, func, lineno, lockstr); \
 		*(mtx_prof) = ast_add_profile(nbuf, 0);							\
     }						                         \
 	*(start) = ast_mark2();							 \
@@ -1476,12 +1476,12 @@
 {
 	return pthread_mutex_destroy(pmutex);
 }
-#define ast_mutex_lock(x) {int start; static int mutprof=-1; ast_mutex_lock2((x), __FILE__, __FUNCTION__,  __LINE__, &start, &mutprof);}
-#define ast_mutex_lock_assign(x,retval) {int start; static int mutprof=-1; retval = ast_mutex_lock2((x), __FILE__, __FUNCTION__,  __LINE__, &start, &mutprof);}
+#define ast_mutex_lock(x) {int start; static int mutprof=-1; ast_mutex_lock2((x), __FILE__, __FUNCTION__,  __LINE__, &start, &mutprof, #x);}
+#define ast_mutex_lock_assign(x,retval) {int start; static int mutprof=-1; retval = ast_mutex_lock2((x), __FILE__, __FUNCTION__,  __LINE__, &start, &mutprof, #x);}
 	
-static inline int ast_mutex_lock2(ast_mutex_t *pmutex, char *file, const char *func, int lineno, int *start, int *mutprof)
-{
-	__MTX_PROF(pmutex, file, func, lineno, start, mutprof);
+static inline int ast_mutex_lock2(ast_mutex_t *pmutex, char *file, const char *func, int lineno, int *start, int *mutprof, char *lockstr)
+{
+	__MTX_PROF(pmutex, file, func, lineno, start, mutprof, lockstr);
 }
 
 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
@@ -1749,13 +1749,16 @@
 #ifndef DEBUG_CHANNEL_LOCKS
 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined 
 	in the Makefile, print relevant output for debugging */
-#define ast_channel_lock(x)		ast_mutex_lock(&x->lock_dont_use)
+#define ast_channel_lock(x)		ast_log(LOG_NOTICE,"LockChan %s\n", x->name); ast_mutex_lock(&x->lock_dont_use); \
+	ast_log(LOG_NOTICE,"LockChan %s OBTAINED\n", x->name);
 /*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined 
 	in the Makefile, print relevant output for debugging */
-#define ast_channel_unlock(x)		ast_mutex_unlock(&x->lock_dont_use)
+#define ast_channel_unlock(x)		ast_log(LOG_NOTICE,"UnLockChan %s\n", x->name); ast_mutex_unlock(&x->lock_dont_use)
+#define ast_channel_unlock_comma(x)		ast_log(LOG_NOTICE,"UnLockChan %s\n", x->name), ast_mutex_unlock(&x->lock_dont_use)
 /*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined 
 	in the Makefile, print relevant output for debugging */
-#define ast_channel_trylock(x)		ast_mutex_trylock(&x->lock_dont_use)
+#define ast_channel_trylock(x)		ast_log(LOG_NOTICE,"TryChan %s\n", x->name); ast_mutex_trylock(&x->lock_dont_use)
+#define ast_channel_trylock_assign(x, var)		ast_log(LOG_NOTICE,"TryChan %s\n", x->name); var = ast_mutex_trylock(&x->lock_dont_use)
 #else
 
 #define ast_channel_lock(a) __ast_channel_lock(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Modified: team/murf/mtxprof/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/main/channel.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/main/channel.c (original)
+++ team/murf/mtxprof/main/channel.c Wed Jun 25 17:46:22 2008
@@ -1013,8 +1013,10 @@
 int ast_queue_hangup(struct ast_channel *chan)
 {
 	struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
+	int lockret;
 	/* Yeah, let's not change a lock-critical value without locking */
-	if (!ast_channel_trylock(chan)) {
+	ast_channel_trylock_assign(chan,lockret);
+	if (!lockret) {
 		chan->_softhangup |= AST_SOFTHANGUP_DEV;
 		ast_channel_unlock(chan);
 	}
@@ -1025,12 +1027,14 @@
 int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
 {
 	struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
+	int lockret;
 
 	if (cause >= 0)
 		f.data.uint32 = cause;
 
 	/* Yeah, let's not change a lock-critical value without locking */
-	if (!ast_channel_trylock(chan)) {
+	ast_channel_trylock_assign(chan,lockret);
+	if (!lockret) {
 		chan->_softhangup |= AST_SOFTHANGUP_DEV;
 		if (cause < 0)
 			f.data.uint32 = chan->hangupcause;
@@ -1113,6 +1117,7 @@
 {
 	const char *msg = prev ? "deadlock" : "initial deadlock";
 	int retries;
+	int lockret;
 	struct ast_channel *c;
 	const struct ast_channel *_prev = prev;
 
@@ -1154,7 +1159,12 @@
 		}
 		/* exit if chan not found or mutex acquired successfully */
 		/* this is slightly unsafe, as we _should_ hold the lock to access c->name */
-		done = c == NULL || ast_channel_trylock(c) == 0;
+		if (c) {
+			ast_log(LOG_NOTICE,"prev=%p; name=%s, len=%d; context=%s; exten=%s\n", prev, name, namelen, context, exten);
+			ast_channel_trylock_assign(c,lockret);
+		}
+			
+		done = c == NULL || lockret == 0;
 		if (!done) {
 			ast_debug(1, "Avoiding %s for channel '%p'\n", msg, c);
 			if (retries == 199) {
@@ -1680,7 +1690,18 @@
 {
 	int res = 0;
 
-	ast_channel_lock(chan);
+#ifdef DEBUG_THREADS
+	
+	static int callcount = 0;
+	if (!((callcount++)%200)) {
+		ast_log(LOG_ERROR,"callcount is %d, channel is %s (%p)\n", callcount, chan->name, chan);
+		
+		log_show_lock(&chan->lock_dont_use);
+	}
+	
+#endif
+	
+	ast_channel_lock(chan); /* in sip runs, this lock eats up a tremendous amount of time */
 
 	/* You can't answer an outbound call */
 	if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
@@ -1838,7 +1859,7 @@
 	
 	/* Perform any pending masquerades */
 	for (x = 0; x < n; x++) {
-		ast_channel_lock(c[x]);
+		ast_channel_lock(c[x]); /* this eats up a tremendous amount of time */
 		if (c[x]->masq && ast_do_masquerade(c[x])) {
 			ast_log(LOG_WARNING, "Masquerade failed\n");
 			*ms = -1;
@@ -2341,15 +2362,18 @@
 	int blah;
 	int prestate;
 	int count = 0, cause = 0;
+	int lockret;
 
 	/* this function is very long so make sure there is only one return
 	 * point at the end (there are only two exceptions to this).
 	 */
-	while(ast_channel_trylock(chan)) {
+	ast_channel_trylock_assign(chan,lockret);
+	while(lockret) {
 		if(count++ > 10) 
 			/*cannot goto done since the channel is not locked*/
 			return &ast_null_frame;
 		usleep(1);
+		ast_channel_trylock_assign(chan,lockret);
 	}
 
 	if (chan->masq) {
@@ -2989,15 +3013,18 @@
 	int res = -1;
 	struct ast_frame *f = NULL, *f2 = NULL;
 	int count = 0;
+	int lockret;
 
 	/*Deadlock avoidance*/
-	while(ast_channel_trylock(chan)) {
+	ast_channel_trylock_assign(chan,lockret);
+	while(lockret) {
 		/*cannot goto done since the channel is not locked*/
 		if(count++ > 10) {
 			ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
 			return 0;
 		}
 		usleep(1);
+		ast_channel_trylock_assign(chan,lockret);
 	}
 	/* Stop if we're a zombie or need a soft hangup */
 	if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
@@ -3636,6 +3663,7 @@
 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
 {
 	int res = -1;
+	int lockret;
 	struct ast_channel *final_orig, *final_clone, *base;
 
 retrymasq:
@@ -3643,10 +3671,12 @@
 	final_clone = clone;
 
 	ast_channel_lock(original);
-	while (ast_channel_trylock(clone)) {
+	ast_channel_trylock_assign(clone,lockret);
+	while (lockret) {
 		ast_channel_unlock(original);
 		usleep(1);
 		ast_channel_lock(original);
+		ast_channel_trylock_assign(clone,lockret);
 	}
 
 	/* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
@@ -3665,12 +3695,14 @@
 		/* Lots and lots of deadlock avoidance.  The main one we're competing with
 		 * is ast_write(), which locks channels recursively, when working with a
 		 * proxy channel. */
-		if (ast_channel_trylock(final_orig)) {
+		ast_channel_trylock_assign(final_orig,lockret);
+		if (lockret) {
 			ast_channel_unlock(clone);
 			ast_channel_unlock(original);
 			goto retrymasq;
 		}
-		if (ast_channel_trylock(final_clone)) {
+		ast_channel_trylock_assign(final_clone,lockret);
+		if (lockret) {
 			ast_channel_unlock(final_orig);
 			ast_channel_unlock(clone);
 			ast_channel_unlock(original);

Modified: team/murf/mtxprof/main/features.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/main/features.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/main/features.c (original)
+++ team/murf/mtxprof/main/features.c Wed Jun 25 17:46:22 2008
@@ -3460,10 +3460,12 @@
 	if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
 		chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
 		chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
-		if (chana)
+		if (chana) {
 			ast_channel_unlock(chana);
-		if (chanb)
+		}
+		if (chanb) {
 			ast_channel_unlock(chanb);
+		}
 
 		/* send errors if any of the channels could not be found/locked */
 		if (!chana) {

Modified: team/murf/mtxprof/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/main/pbx.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/main/pbx.c (original)
+++ team/murf/mtxprof/main/pbx.c Wed Jun 25 17:46:22 2008
@@ -2345,8 +2345,9 @@
 			*ret = substring(*ret, offset, length, workspace, workspacelen);
 	}
 
-	if (c)
+	if (c) {
 		ast_channel_unlock(c);
+	}
 }
 
 static void exception_store_free(void *data)
@@ -6823,8 +6824,9 @@
 		chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
 		if (channel) {
 			*channel = chan;
-			if (chan)
+			if (chan) {
 				ast_channel_lock(chan);
+			}
 		}
 		if (chan) {
 			if (chan->_state == AST_STATE_UP) {
@@ -6832,8 +6834,9 @@
 				ast_verb(4, "Channel %s was answered.\n", chan->name);
 
 				if (sync > 1) {
-					if (channel)
+					if (channel) {
 						ast_channel_unlock(chan);
+					}
 					if (ast_pbx_run(chan)) {
 						ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
 						if (channel)
@@ -6913,8 +6916,9 @@
 		chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
 		if (channel) {
 			*channel = chan;
-			if (chan)
+			if (chan) {
 				ast_channel_lock(chan);
+			}
 		}
 		if (!chan) {
 			ast_free(as);
@@ -7016,17 +7020,20 @@
 						ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
 					tmp->chan = chan;
 					if (sync > 1) {
-						if (locked_channel)
+						if (locked_channel) {
 							ast_channel_unlock(chan);
+						}
 						ast_pbx_run_app(tmp);
 					} else {
-						if (locked_channel)
+						if (locked_channel) {
 							ast_channel_lock(chan);
+						}
 						if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
 							ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
 							ast_free(tmp);
-							if (locked_channel)
+							if (locked_channel) {
 								ast_channel_unlock(chan);
+							}
 							ast_hangup(chan);
 							res = -1;
 						} else {
@@ -7079,13 +7086,15 @@
 		if (account)
 			ast_cdr_setaccount(chan, account);
 		/* Start a new thread, and get something handling this channel. */
-		if (locked_channel)
+		if (locked_channel) {
 			ast_channel_lock(chan);
+		}
 		if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
 			ast_log(LOG_WARNING, "Failed to start async wait\n");
 			ast_free(as);
-			if (locked_channel)
+			if (locked_channel) {
 				ast_channel_unlock(chan);
+			}
 			ast_hangup(chan);
 			res = -1;
 			goto outgoing_app_cleanup;
@@ -7730,8 +7739,9 @@
 			break;
 	}
 
-	if (chan)
+	if (chan) {
 		ast_channel_unlock(chan);
+	}
 
 	return ret;
 }
@@ -7764,10 +7774,11 @@
 		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
 	}
 
-	if (chan)
+	if (chan) {
 		ast_channel_unlock(chan);
-	else
+	} else {
 		ast_rwlock_unlock(&globalslock);
+	}
 }
 
 void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
@@ -7821,10 +7832,12 @@
 			chan ? chan->uniqueid : "none");
 	}
 
-	if (chan)
+	if (chan) {
 		ast_channel_unlock(chan);
-	else
+	} else {
 		ast_rwlock_unlock(&globalslock);
+	}
+	
 }
 
 int pbx_builtin_setvar(struct ast_channel *chan, void *data)

Modified: team/murf/mtxprof/main/rtp.c
URL: http://svn.digium.com/view/asterisk/team/murf/mtxprof/main/rtp.c?view=diff&rev=125137&r1=125136&r2=125137
==============================================================================
--- team/murf/mtxprof/main/rtp.c (original)
+++ team/murf/mtxprof/main/rtp.c Wed Jun 25 17:46:22 2008
@@ -2015,10 +2015,13 @@
 	/* Lock channels */
 	ast_channel_lock(c0);
 	if (c1) {
-		while (ast_channel_trylock(c1)) {
+		int lockret;
+		ast_channel_trylock_assign(c1,lockret);
+		while (lockret) {
 			ast_channel_unlock(c0);
 			usleep(1);
 			ast_channel_lock(c0);
+			ast_channel_trylock_assign(c1,lockret);
 		}
 	}
 
@@ -2029,15 +2032,17 @@
 	if (!destpr) {
 		ast_debug(1, "Channel '%s' has no RTP, not doing anything\n", c0->name);
 		ast_channel_unlock(c0);
-		if (c1)
+		if (c1) {
 			ast_channel_unlock(c1);
+		}
 		return -1;
 	}
 	if (!srcpr) {
 		ast_debug(1, "Channel '%s' has no RTP, not doing anything\n", c1 ? c1->name : "<unspecified>");
 		ast_channel_unlock(c0);
-		if (c1)
+		if (c1) {
 			ast_channel_unlock(c1);
+		}
 		return -1;
 	}
 
@@ -2055,8 +2060,9 @@
 	if (audio_dest_res != AST_RTP_TRY_NATIVE) {
 		/* Somebody doesn't want to play... */
 		ast_channel_unlock(c0);
-		if (c1)
+		if (c1) {
 			ast_channel_unlock(c1);
+		}
 		return -1;
 	}
 	if (audio_src_res == AST_RTP_TRY_NATIVE && srcpr->get_codec)
@@ -2070,8 +2076,9 @@
 	/* Ensure we have at least one matching codec */
 	if (!(srccodec & destcodec)) {
 		ast_channel_unlock(c0);
-		if (c1)
+		if (c1) {
 			ast_channel_unlock(c1);
+		}
 		return 0;
 	}
 	/* Consider empty media as non-existent */
@@ -2083,8 +2090,9 @@

[... 158 lines stripped ...]



More information about the svn-commits mailing list