[asterisk-commits] dvossel: branch 1.6.1 r259930 - in /branches/1.6.1: ./ channels/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 28 16:33:22 CDT 2010


Author: dvossel
Date: Wed Apr 28 16:33:16 2010
New Revision: 259930

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=259930
Log:
Merged revisions 259870 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r259870 | dvossel | 2010-04-28 16:20:03 -0500 (Wed, 28 Apr 2010) | 39 lines
  
  Merged revisions 259858 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r259858 | dvossel | 2010-04-28 16:16:03 -0500 (Wed, 28 Apr 2010) | 33 lines
    
    resolves deadlocks in chan_local
    
    Issue_1.
    In the local_hangup() 3 locks must be held at the same time... pvt, pvt->chan,
    and pvt->owner.  Proper deadlock avoidance is done when the channel to hangup
    is the outbound chan_local channel, but when it is not the outbound channel we
    have an issue... We attempt to do deadlock avoidance only on the tech pvt, when
    both the tech pvt and the pvt->owner are locked coming into that loop.  By
    never giving up the pvt->owner channel deadlock avoidance is not entirely possible.
    This patch resolves that by doing deadlock avoidance on both the pvt->owner and the pvt
    when trying to get the pvt->chan lock.
    
    Issue_2.
    ast_prod() is used in ast_activate_generator() to queue a frame on the channel
    and make the channel's read function get called.  This function is used in
    ast_activate_generator() while the channel is locked, which mean's the channel
    will have a lock both from the generator code and the frame_queue code by the
    time it gets to chan_local.c's local_queue_frame code... local_queue_frame
    contains some of the same crazy deadlock avoidance that local_hangup requires,
    and this recursive lock prevents that deadlock avoidance from happening correctly.
    This patch removes ast_prod() from the channel lock so only one lock is held during
    the local_queue_frame function.
    
    (closes issue #17185)
    Reported by: schmoozecom
    Patches:
          issue_17185_v1.diff uploaded by dvossel (license 671)
          issue_17185_v2.diff uploaded by dvossel (license 671)
    Tested by: schmoozecom, GameGamer43
    
    Review: https://reviewboard.asterisk.org/r/631/
  ........
................

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/channels/chan_local.c
    branches/1.6.1/main/channel.c

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

Modified: branches/1.6.1/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/channels/chan_local.c?view=diff&rev=259930&r1=259929&r2=259930
==============================================================================
--- branches/1.6.1/channels/chan_local.c (original)
+++ branches/1.6.1/channels/chan_local.c Wed Apr 28 16:33:16 2010
@@ -580,12 +580,12 @@
 			/* Deadlock avoidance */
 			while (p->owner && ast_channel_trylock(p->owner)) {
 				ast_mutex_unlock(&p->lock);
-				if (ast) {
-					ast_channel_unlock(ast);
+				if (p->chan) {
+					ast_channel_unlock(p->chan);
 				}
 				usleep(1);
-				if (ast) {
-					ast_channel_lock(ast);
+				if (p->chan) {
+					ast_channel_lock(p->chan);
 				}
 				ast_mutex_lock(&p->lock);
 			}
@@ -600,8 +600,17 @@
 	} else {
 		ast_module_user_remove(p->u_owner);
 		while (p->chan && ast_channel_trylock(p->chan)) {
-			DEADLOCK_AVOIDANCE(&p->lock);
-		}
+				ast_mutex_unlock(&p->lock);
+				if (p->owner) {
+					ast_channel_unlock(p->owner);
+				}
+				usleep(1);
+				if (p->owner) {
+					ast_channel_lock(p->owner);
+				}
+				ast_mutex_lock(&p->lock);
+		}
+
 		p->owner = NULL;
 		if (p->chan) {
 			ast_queue_hangup(p->chan);

Modified: branches/1.6.1/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/main/channel.c?view=diff&rev=259930&r1=259929&r2=259930
==============================================================================
--- branches/1.6.1/main/channel.c (original)
+++ branches/1.6.1/main/channel.c Wed Apr 28 16:33:16 2010
@@ -1982,24 +1982,21 @@
 	int res = 0;
 
 	ast_channel_lock(chan);
-
 	if (chan->generatordata) {
 		if (chan->generator && chan->generator->release)
 			chan->generator->release(chan, chan->generatordata);
 		chan->generatordata = NULL;
 	}
-
-	ast_prod(chan);
 	if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
 		res = -1;
 	}
-	
 	if (!res) {
 		ast_settimeout(chan, 50, generator_force, chan);
 		chan->generator = gen;
 	}
-
 	ast_channel_unlock(chan);
+
+	ast_prod(chan);
 
 	return res;
 }




More information about the asterisk-commits mailing list