summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-12-20 20:16:21 +0000
committerRussell Bryant <russell@russellbryant.com>2007-12-20 20:16:21 +0000
commitd607a29ddfbd351be338b1742deeacad165035c6 (patch)
tree016a78b350484763b94465a196a3d7a69640c315 /channels
parentb7adaa023c216acb6bd494a27758e4d6bfbed72d (diff)
Merged revisions 94251 via svnmerge from
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
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_zap.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index ebbf3c8f6..c7fb05447 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -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