[Asterisk-cvs] asterisk/channels chan_zap.c,1.171.2.3,1.171.2.4

markster at lists.digium.com markster at lists.digium.com
Fri Feb 20 16:36:38 CST 2004


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

Modified Files:
      Tag: v1-0_stable
	chan_zap.c 
Log Message:
Be sure to lock both slave and master while performing unlinkage


Index: chan_zap.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v
retrieving revision 1.171.2.3
retrieving revision 1.171.2.4
diff -u -d -r1.171.2.3 -r1.171.2.4
--- chan_zap.c	18 Feb 2004 16:33:34 -0000	1.171.2.3
+++ chan_zap.c	20 Feb 2004 21:24:07 -0000	1.171.2.4
@@ -2193,13 +2193,23 @@
 	return 0;
 }
 
-static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master)
+static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
 {
 	/* Unlink a specific slave or all slaves/masters from a given master */
 	int x;
 	int hasslaves;
 	if (!master)
 		return;
+	if (needlock) {
+		ast_mutex_lock(&master->lock);
+		if (slave) {
+			while(ast_mutex_trylock(&slave->lock)) {
+				ast_mutex_unlock(&master->lock);
+				usleep(1);
+				ast_mutex_lock(&master->lock);
+			}
+		}
+	}
 	hasslaves = 0;
 	for (x=0;x<MAX_SLAVES;x++) {
 		if (master->slaves[x]) {
@@ -2234,6 +2244,11 @@
 		master->master = NULL;
 	}
 	update_conf(master);
+	if (needlock) {
+		if (slave)
+			ast_mutex_unlock(&slave->lock);
+		ast_mutex_unlock(&master->lock);
+	}
 }
 
 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
@@ -2453,7 +2468,7 @@
 			(oi1 != i1) ||
 			(oi2 != i2)) {
 			if (slave && master)
-				zt_unlink(slave, master);
+				zt_unlink(slave, master, 1);
 			ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
 									op0->channel, oi1, op1->channel, oi2);
 			if (op0 == p0)
@@ -2481,7 +2496,7 @@
 			*fo = NULL;
 			*rc = who;
 			if (slave && master)
-				zt_unlink(slave, master);
+				zt_unlink(slave, master, 1);
 			if (op0 == p0)
 				zt_enable_ec(p0);
 			if (op1 == p1)
@@ -2494,7 +2509,7 @@
 				*fo = f;
 				*rc = who;
 				if (slave && master)
-					zt_unlink(slave, master);
+					zt_unlink(slave, master, 1);
 				return 0;
 			} else if ((who == c0) && p0->pulsedial) {
 				ast_write(c1, f);
@@ -2517,18 +2532,20 @@
 {
 	struct zt_pvt *p = newchan->pvt->pvt;
 	int x;
+	ast_mutex_lock(&p->lock);
 	ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
 	if (p->owner == oldchan)
 		p->owner = newchan;
 	for (x=0;x<3;x++)
 		if (p->subs[x].owner == oldchan) {
 			if (!x)
-				zt_unlink(NULL, p);
+				zt_unlink(NULL, p, 0);
 			p->subs[x].owner = newchan;
 		}
 	if (newchan->_state == AST_STATE_RINGING) 
 		zt_indicate(newchan, AST_CONTROL_RINGING);
 	update_conf(p);
+	ast_mutex_unlock(&p->lock);
 	return 0;
 }
 




More information about the svn-commits mailing list