[Asterisk-cvs] asterisk/channels chan_zap.c,1.335,1.336

markster at lists.digium.com markster at lists.digium.com
Fri Sep 10 14:45:13 CDT 2004


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv15281/channels

Modified Files:
	chan_zap.c 
Log Message:
Make sure we don't try to grab the sub and channel locks while still having the PRI lock! (bug #2392)


Index: chan_zap.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v
retrieving revision 1.335
retrieving revision 1.336
diff -u -d -r1.335 -r1.336
--- chan_zap.c	10 Sep 2004 15:11:37 -0000	1.335
+++ chan_zap.c	10 Sep 2004 18:47:13 -0000	1.336
@@ -631,9 +631,17 @@
 	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 @@
 		} 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 @@
 		} 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 @@
 		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 @@
 				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 @@
 								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 @@
 						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 @@
 						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 @@
 	}
 	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;




More information about the svn-commits mailing list