]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 94251 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Thu, 20 Dec 2007 20:16:21 +0000 (20:16 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 20 Dec 2007 20:16:21 +0000 (20:16 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r94251 | russell | 2007-12-20 14:08:42 -0600 (Thu, 20 Dec 2007) | 10 lines

Fix a deadlock in d-channel handling in chan_zap.

This deadlock was introduced by the fix to ensure that channels are properly
locked when handling channel variables.  There were sections of this code where
the channel pvt was locked before the channel lock, when in fact it _must_ be
the other way around.

(closes issue #11582)
Reported by: bugi

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@94252 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_zap.c

index ebbf3c8f60aff2861fa6733077593b525a02a19d..c7fb054475a2bc4ee22176a9e9ad04b10076888e 100644 (file)
@@ -10206,6 +10206,9 @@ static void *pri_dchannel(void *vpri)
                                                        } else {
                                                                c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
                                                        }
+
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+
                                                        if (!ast_strlen_zero(e->ring.callingsubaddr)) {
                                                                pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
                                                        }
@@ -10225,7 +10228,8 @@ static void *pri_dchannel(void *vpri)
                                                        pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
                                                        if (e->ring.redirectingreason >= 0)
                                                                pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
-                                                       
+                                               
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                        ast_mutex_lock(&pri->lock);
                                                        if (c && !ast_pthread_create_detached(&threadid, NULL, ss_thread, c)) {
                                                                ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
@@ -10245,9 +10249,11 @@ static void *pri_dchannel(void *vpri)
                                                        ast_mutex_unlock(&pri->lock);
                                                        /* Release PRI lock while we create the channel */
                                                        c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
-                                                       ast_mutex_lock(&pri->lock);
                                                        if (c) {
                                                                char calledtonstr[10];
+
+                                                               ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+
                                                                if (e->ring.ani2 >= 0) {
                                                                        snprintf(ani2str, 5, "%d", e->ring.ani2);
                                                                        pbx_builtin_setvar_helper(c, "ANI2", ani2str);
@@ -10265,11 +10271,19 @@ static void *pri_dchannel(void *vpri)
                                                        
                                                                snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
                                                                pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
+
+                                                               ast_mutex_lock(&pri->pvts[chanpos]->lock);
+                                                               ast_mutex_lock(&pri->lock);
+
                                                                ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
                                                                                plancallingnum, pri->pvts[chanpos]->exten, 
-                                                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
+                                                                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
+
                                                                zt_enable_ec(pri->pvts[chanpos]);
                                                        } else {
+
+                                                               ast_mutex_lock(&pri->lock);
+
                                                                ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
                                                                        pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
                                                                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
@@ -10328,7 +10342,10 @@ static void *pri_dchannel(void *vpri)
 
 #ifdef SUPPORT_USERUSER
                                                if (!ast_strlen_zero(e->ringing.useruserinfo)) {
+                                                       struct ast_channel *owner = pri->pvts[chanpos]->owner;
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->ringing.useruserinfo);
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                }
 #endif
 
@@ -10482,7 +10499,10 @@ static void *pri_dchannel(void *vpri)
 
 #ifdef SUPPORT_USERUSER
                                                if (!ast_strlen_zero(e->answer.useruserinfo)) {
+                                                       struct ast_channel *owner = pri->pvts[chanpos]->owner;
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->answer.useruserinfo);
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                }
 #endif
 
@@ -10545,7 +10565,10 @@ static void *pri_dchannel(void *vpri)
 
 #ifdef SUPPORT_USERUSER
                                                if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
+                                                       struct ast_channel *owner = pri->pvts[chanpos]->owner;
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                }
 #endif
 
@@ -10608,7 +10631,10 @@ static void *pri_dchannel(void *vpri)
 
 #ifdef SUPPORT_USERUSER
                                                if (!ast_strlen_zero(e->hangup.useruserinfo)) {
+                                                       struct ast_channel *owner = pri->pvts[chanpos]->owner;
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                }
 #endif
 
@@ -10635,7 +10661,10 @@ static void *pri_dchannel(void *vpri)
 
 #ifdef SUPPORT_USERUSER
                                                if (!ast_strlen_zero(e->hangup.useruserinfo)) {
+                                                       struct ast_channel *owner = pri->pvts[chanpos]->owner;
+                                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
+                                                       ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                }
 #endif