[svn-commits] mmichelson: branch 1.6.2 r199591 - in /branches/1.6.2: ./ channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jun 8 12:42:32 CDT 2009


Author: mmichelson
Date: Mon Jun  8 12:42:27 2009
New Revision: 199591

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=199591
Log:
Recorded merge of revisions 199588 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r199588 | mmichelson | 2009-06-08 12:32:04 -0500 (Mon, 08 Jun 2009) | 9 lines
  
  Fix a deadlock that could occur when setting rtp stats on SIP calls.
  
  (closes issue #15143)
  Reported by: cristiandimache
  Patches:
        15143.patch uploaded by mmichelson (license 60)
  Tested by: cristiandimache
........

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/channels/chan_sip.c

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.2/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.2/channels/chan_sip.c?view=diff&rev=199591&r1=199590&r2=199591
==============================================================================
--- branches/1.6.2/channels/chan_sip.c (original)
+++ branches/1.6.2/channels/chan_sip.c Mon Jun  8 12:42:27 2009
@@ -5730,6 +5730,21 @@
 				char *videoqos = "";
 				char *textqos = "";
 
+				/* We need to get the lock on bridge because ast_rtp_set_vars will attempt
+				 * to lock the bridge. This may get hairy...
+				 */
+				while (bridge && ast_channel_trylock(bridge)) {
+					struct ast_channel *chan = p->owner;
+					sip_pvt_unlock(p);
+					do {
+						/* Use chan since p->owner could go NULL on us
+						 * while p is unlocked
+						 */
+						CHANNEL_DEADLOCK_AVOIDANCE(chan);
+					} while (sip_pvt_trylock(p));
+					bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
+				}
+
 				if (p->rtp)
 					ast_rtp_set_vars(oldowner, p->rtp);
 
@@ -5738,6 +5753,7 @@
 
 					if (IS_SIP_TECH(bridge->tech) && q && q->rtp)
 						ast_rtp_set_vars(bridge, q->rtp);
+					ast_channel_unlock(bridge);
 				}
 
 				if (p->vrtp)
@@ -20159,6 +20175,20 @@
 		struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
 		char *videoqos, *textqos;
 
+		/* We need to get the lock on bridge because ast_rtp_set_vars will attempt
+		 * to lock the bridge. This may get hairy...
+		 */
+		while (bridge && ast_channel_trylock(bridge)) {
+			ast_channel_unlock(p->owner);
+			do {
+				/* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
+				sip_pvt_unlock(p);
+				usleep(1);
+				sip_pvt_lock(p);
+			} while (p->owner && ast_channel_trylock(p->owner));
+			bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
+		}
+
 		if (p->rtp) {	
 			if (p->do_history) {
 				char *audioqos,
@@ -20187,6 +20217,7 @@
 
 			if (IS_SIP_TECH(bridge->tech) && q && q->rtp)
 				ast_rtp_set_vars(bridge, q->rtp);
+			ast_channel_unlock(bridge);
 		}
 
 		if (p->vrtp) {




More information about the svn-commits mailing list