[asterisk-commits] russell: trunk r315447 - in /trunk: ./ channels/chan_local.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 26 12:41:57 CDT 2011


Author: russell
Date: Tue Apr 26 12:41:51 2011
New Revision: 315447

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=315447
Log:
Merged revisions 315446 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r315446 | russell | 2011-04-26 12:40:23 -0500 (Tue, 26 Apr 2011) | 14 lines
  
  chan_local: resolve a deadlock.
  
  This patch resolves a fairly complex deadlock that can occur with the
  combination of chan_local and a dialplan switch, such as dynamic realtime
  extensions, which pulls autoservice into the picture when doing a dialplan
  lookup.
  
  (closes issue #18818)
  Reported by: nic
  Patches:
        issue18818.patch uploaded by jthurman (license 614)
        18818.v1.txt uploaded by russell (license 2)
  Tested by: nic, jthurman, kterzi, steve-howes, sysreq, IshMalik
........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_local.c

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

Modified: trunk/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_local.c?view=diff&rev=315447&r1=315446&r2=315447
==============================================================================
--- trunk/channels/chan_local.c (original)
+++ trunk/channels/chan_local.c Tue Apr 26 12:41:51 2011
@@ -736,6 +736,9 @@
 	size_t len, namelen;
 	char *reduced_dest = ast_strdupa(dest);
 	char *slash;
+	struct ast_channel *chan;
+	const char *exten;
+	const char *context;
 
 	if (!p || p->owner != ast) {
 		return -1;
@@ -820,21 +823,28 @@
 	}
 	ast_set_cc_interfaces_chanvar(p->chan, reduced_dest);
 
-	if (!ast_exists_extension(p->chan, p->chan->context, p->chan->exten, 1,
+	chan = ast_channel_ref(p->chan);
+	ao2_unlock(p);
+	exten = ast_strdupa(chan->exten);
+	context = ast_strdupa(chan->context);
+	ast_channel_unlock(chan);
+
+	if (!ast_exists_extension(chan, context, exten, 1,
 		S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
-		ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", p->chan->exten, p->chan->context);
-		ao2_unlock(p);
-		ast_channel_unlock(p->chan);
-		ao2_ref(p, -1);
-		return -1;
+		ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
+		res = -1;
+		goto return_cleanup;
 	}
 
 	/* Start switch on sub channel */
-	if (!(res = ast_pbx_start(p->chan)))
+	if (!(res = ast_pbx_start(chan))) {
+		ao2_lock(p);
 		ast_set_flag(p, LOCAL_LAUNCHED_PBX);
-
-	ao2_unlock(p);
-	ast_channel_unlock(p->chan);
+		ao2_unlock(p);
+	}
+
+return_cleanup:
+	ast_channel_unref(chan);
 	ao2_ref(p, -1);
 	return res;
 }




More information about the asterisk-commits mailing list