summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-08-14 04:07:00 +0000
committerrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-08-14 04:07:00 +0000
commitbe370e2b5b974e1de4751e8ff966bcb6be2100e3 (patch)
tree30a6584161788b4168419adc1fc8a9a1a481663e
parent0c19cd4ccf531e5d705e7d61a7ef345f31ed63c7 (diff)
fix potential deadlock found by kernel's lock checker
(issue #7620, reported by smurfix, fixed by Corydon) git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1304 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--zaptel.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/zaptel.c b/zaptel.c
index 4cc996d..6b7793f 100644
--- a/zaptel.c
+++ b/zaptel.c
@@ -1091,8 +1091,14 @@ static int set_tone_zone(struct zt_chan *chan, int zone)
/* Assumes channel is already locked */
if ((zone >= ZT_TONE_ZONE_MAX) || (zone < -1))
return -EINVAL;
-
- read_lock(&zone_lock);
+
+ /* Since this routine is called both from IRQ as well as from userspace,
+ * it is possible that we could be called during an IRQ while userspace
+ * has locked this. However unlikely, this could possibly cause a
+ * deadlock. */
+ if (! read_trylock(&zone_lock))
+ return -EWOULDBLOCK;
+
if (zone == -1) {
zone = default_zone;
}
@@ -1103,7 +1109,7 @@ static int set_tone_zone(struct zt_chan *chan, int zone)
} else {
res = -ENODATA;
}
-
+
read_unlock(&zone_lock);
return res;
}