diff options
author | netchild <netchild@FreeBSD.org> | 2005-09-10 17:51:38 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2005-09-10 17:51:38 +0000 |
commit | c0f53576aa5ac177315bef513e401b2e2bd90ed1 (patch) | |
tree | bf2ca4c195334304d6160ace8ff14ff4c3712c50 /sys/dev/sound/pcm/dsp.c | |
parent | a0eea69ee0b3b1673831b2e804443c76fccab6d7 (diff) | |
download | FreeBSD-src-c0f53576aa5ac177315bef513e401b2e2bd90ed1.zip FreeBSD-src-c0f53576aa5ac177315bef513e401b2e2bd90ed1.tar.gz |
Release lock for a while during chn_reset() / pcm_chnalloc() operation
while malloc()ing, this fixes LOR 129.
See
- http://lists.freebsd.org/pipermail/freebsd-current/2005-June/051157.html
- http://lists.freebsd.org/pipermail/freebsd-current/2005-August/054620.html
- http://sources.zabbadoz.net/freebsd/lor.html#129
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Diffstat (limited to 'sys/dev/sound/pcm/dsp.c')
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 9c34f65..b10e5bd 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -241,13 +241,13 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) */ if (flags & FREAD) { /* open for read */ + pcm_unlock(d); if (devtype == SND_DEV_DSPREC) rdch = pcm_chnalloc(d, PCMDIR_REC, td->td_proc->p_pid, PCMCHAN(i_dev)); else rdch = pcm_chnalloc(d, PCMDIR_REC, td->td_proc->p_pid, -1); if (!rdch) { /* no channel available, exit */ - pcm_unlock(d); splx(s); return EBUSY; } @@ -255,11 +255,11 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) if (chn_reset(rdch, fmt)) { pcm_chnrelease(rdch); i_dev->si_drv1 = NULL; - pcm_unlock(d); splx(s); return ENODEV; } + pcm_lock(d); if (flags & O_NONBLOCK) rdch->flags |= CHN_F_NBIO; pcm_chnref(rdch, 1); @@ -272,6 +272,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) if (flags & FWRITE) { /* open for write */ + pcm_unlock(d); wrch = pcm_chnalloc(d, PCMDIR_PLAY, td->td_proc->p_pid, -1); error = 0; @@ -280,6 +281,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) else if (chn_reset(wrch, fmt)) error = ENODEV; + pcm_lock(d); if (error != 0) { if (wrch) { /* @@ -950,6 +952,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * *arg_i = 24; else if (chn->format & AFMT_32BIT) *arg_i = 32; + else + ret = EINVAL; CHN_UNLOCK(chn); break; |