diff options
author | russell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-08-14 04:07:00 +0000 |
---|---|---|
committer | russell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-08-14 04:07:00 +0000 |
commit | be370e2b5b974e1de4751e8ff966bcb6be2100e3 (patch) | |
tree | 30a6584161788b4168419adc1fc8a9a1a481663e | |
parent | 0c19cd4ccf531e5d705e7d61a7ef345f31ed63c7 (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.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -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; } |