diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-09-10 18:47:13 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-09-10 18:47:13 +0000 |
commit | fac86b8000bbf1d1ac79cc5e4efcf317fa8bf271 (patch) | |
tree | 3008fa145fb84c119d7b339036b0adcc559d8f22 | |
parent | 2b772ac9646c71e87a787047a311c7e5b61a2d07 (diff) |
Make sure we don't try to grab the sub and channel locks while still having the PRI lock! (bug #2392)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3760 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-x | channels/chan_zap.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/channels/chan_zap.c b/channels/chan_zap.c index e17af276a..0b1b1e79c 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -631,9 +631,17 @@ static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok) return res; } -static void wakeup_sub(struct zt_pvt *p, int a) +#ifdef ZAPATA_PRI +static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri) +#else +static void wakeup_sub(struct zt_pvt *p, int a, void *pri) +#endif { struct ast_frame null = { AST_FRAME_NULL, }; +#ifdef ZAPATA_PRI + if (pri) + ast_mutex_unlock(&pri->lock); +#endif for (;;) { if (p->subs[a].owner) { if (ast_mutex_trylock(&p->subs[a].owner->lock)) { @@ -648,10 +656,23 @@ static void wakeup_sub(struct zt_pvt *p, int a) } else break; } +#ifdef ZAPATA_PRI + if (pri) + ast_mutex_lock(&pri->lock); +#endif } -static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f) +#ifdef ZAPATA_PRI +static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri) +#else +static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri) +#endif { + /* We must unlock the PRI to avoid the possibility of a deadlock */ +#ifdef ZAPATA_PRI + if (pri) + ast_mutex_unlock(&pri->lock); +#endif for (;;) { if (p->owner) { if (ast_mutex_trylock(&p->owner->lock)) { @@ -666,6 +687,10 @@ static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f) } else break; } +#ifdef ZAPATA_PRI + if (pri) + ast_mutex_lock(&pri->lock); +#endif } static void swap_subs(struct zt_pvt *p, int a, int b) @@ -692,8 +717,8 @@ static void swap_subs(struct zt_pvt *p, int a, int b) p->subs[a].owner->fds[0] = p->subs[a].zfd; if (p->subs[b].owner) p->subs[b].owner->fds[0] = p->subs[b].zfd; - wakeup_sub(p, a); - wakeup_sub(p, b); + wakeup_sub(p, a, NULL); + wakeup_sub(p, b, NULL); } static int zt_open(char *fn) @@ -6754,7 +6779,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c) ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n", pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset, pri->trunkgroup, crv->channel); - wakeup_sub(crv, SUB_REAL); + wakeup_sub(crv, SUB_REAL, pri); } return principle; } @@ -7202,7 +7227,7 @@ static void *pri_dchannel(void *vpri) digit = e->ring.callednum[i]; { struct ast_frame f = { AST_FRAME_DTMF, digit, }; - zap_queue_frame(pri->pvts[chanpos], &f); + zap_queue_frame(pri->pvts[chanpos], &f, pri); } } } @@ -7426,7 +7451,7 @@ static void *pri_dchannel(void *vpri) ast_mutex_lock(&pri->pvts[chanpos]->lock); ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); - zap_queue_frame(pri->pvts[chanpos], &f); + zap_queue_frame(pri->pvts[chanpos], &f, pri); ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } @@ -7440,9 +7465,9 @@ static void *pri_dchannel(void *vpri) ast_mutex_lock(&pri->pvts[chanpos]->lock); ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); - zap_queue_frame(pri->pvts[chanpos], &f); + zap_queue_frame(pri->pvts[chanpos], &f, pri); f.subclass = AST_CONTROL_PROCEEDING; - zap_queue_frame(pri->pvts[chanpos], &f); + zap_queue_frame(pri->pvts[chanpos], &f, pri); pri->pvts[chanpos]->proceeding=2; ast_mutex_unlock(&pri->pvts[chanpos]->lock); } @@ -8489,7 +8514,7 @@ static int action_zapdialoffhook(struct mansession *s, struct message *m) } for (i=0; i<strlen(number); i++) { struct ast_frame f = { AST_FRAME_DTMF, number[i] }; - zap_queue_frame(p, &f); + zap_queue_frame(p, &f, NULL); } astman_send_ack(s, m, "ZapDialOffhook"); return 0; |