[svn-commits] sruffell: branch 1.4 r3733 - in /branches: 1.2/zaptel-base.c 1.4/zaptel-base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jan 23 17:02:05 CST 2008


Author: sruffell
Date: Wed Jan 23 17:02:05 2008
New Revision: 3733

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3733
Log:
Ensure that the zone lock is always acquired before the channel lock.  

(issue #7620)

Modified:
    branches/1.2/zaptel-base.c
    branches/1.4/zaptel-base.c

Change Statistics:
 0 files changed

Modified: branches/1.2/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/zaptel-base.c?view=diff&rev=3733&r1=3732&r2=3733
==============================================================================
--- branches/1.2/zaptel-base.c (original)
+++ branches/1.2/zaptel-base.c Wed Jan 23 17:02:05 2008
@@ -1131,8 +1131,9 @@
 
 static int set_tone_zone(struct zt_chan *chan, int zone)
 {
+	unsigned long flags;
 	int res=0;
-	/* Assumes channel is already locked */
+	/* Do not call with the channel locked. */
 	if ((zone >= ZT_TONE_ZONE_MAX) || (zone < -1))
 		return -EINVAL;
 
@@ -1142,9 +1143,11 @@
 		zone = default_zone;
 	}
 	if (tone_zones[zone]) {
+		spin_lock_irqsave(&chan->lock, flags);
 		chan->curzone = tone_zones[zone];
 		chan->tonezone = zone;
 		memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence));
+		spin_unlock_irqrestore(&chan->lock, flags);
 	} else {
 		res = -ENODATA;
 	}
@@ -2157,7 +2160,6 @@
 	chan->curtone = NULL;
 	chan->tonep = 0;
 	chan->pdialcount = 0;
-	set_tone_zone(chan, -1);
 	if (chan->gainalloc && chan->rxgain)
 		rxgain = chan->rxgain;
 	chan->rxgain = defgain;
@@ -2186,6 +2188,7 @@
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
+	set_tone_zone(chan, -1);
 
 	if (chan->span && chan->span->echocan)
 		chan->span->echocan(chan, 0);
@@ -3762,9 +3765,7 @@
 		break;
 	case ZT_SETTONEZONE:
 		get_user(j,(int *)data);
-		spin_lock_irqsave(&chan->lock, flags);
 		rv =  set_tone_zone(chan, j);
-		spin_unlock_irqrestore(&chan->lock, flags);
 		return rv;
 	case ZT_GETTONEZONE:
 		spin_lock_irqsave(&chan->lock, flags);

Modified: branches/1.4/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/zaptel-base.c?view=diff&rev=3733&r1=3732&r2=3733
==============================================================================
--- branches/1.4/zaptel-base.c (original)
+++ branches/1.4/zaptel-base.c Wed Jan 23 17:02:05 2008
@@ -1179,8 +1179,9 @@
 {
 	int res = 0;
 	struct zt_zone *z;
-
-	/* Assumes channel is already locked */
+	unsigned long flags;
+
+	/* Do not call with the channel locked. */
 
 	if (zone == -1)
 		zone = default_zone;
@@ -1191,6 +1192,7 @@
 	read_lock(&zone_lock);
 
 	if ((z = tone_zones[zone])) {
+		spin_lock_irqsave(&chan->lock, flags);
 		if (chan->curzone)
 			atomic_dec(&chan->curzone->refcount);
 
@@ -1198,6 +1200,7 @@
 		chan->curzone = z;
 		chan->tonezone = zone;
 		memcpy(chan->ringcadence, z->ringcadence, sizeof(chan->ringcadence));
+		spin_unlock_irqrestore(&chan->lock, flags);
 	} else {
 		res = -ENODATA;
 	}
@@ -2266,7 +2269,6 @@
 	chan->curtone = NULL;
 	chan->tonep = 0;
 	chan->pdialcount = 0;
-	set_tone_zone(chan, -1);
 	if (chan->gainalloc && chan->rxgain)
 		rxgain = chan->rxgain;
 	chan->rxgain = defgain;
@@ -2295,6 +2297,7 @@
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
+	set_tone_zone(chan, -1);
 
 	if (chan->span && chan->span->echocan)
 		chan->span->echocan(chan, 0);
@@ -2382,8 +2385,9 @@
 			spin_lock_irqsave(&chans[unit]->lock, flags);
 			if (chans[unit]->flags & ZT_FLAG_PSEUDO) 
 				chans[unit]->flags |= ZT_FLAG_AUDIO;
-			if (chans[unit]->span && chans[unit]->span->open)
+			if (chans[unit]->span && chans[unit]->span->open) {
 				res = chans[unit]->span->open(chans[unit]);
+			}
 			if (!res) {
 				chans[unit]->file = file;
 #ifndef LINUX26
@@ -4017,9 +4021,7 @@
 		break;
 	case ZT_SETTONEZONE:
 		get_user(j, (int *) data);
-		spin_lock_irqsave(&chan->lock, flags);
 		rv = set_tone_zone(chan, j);
-		spin_unlock_irqrestore(&chan->lock, flags);
 		return rv;
 	case ZT_GETTONEZONE:
 		spin_lock_irqsave(&chan->lock, flags);




More information about the svn-commits mailing list