diff options
author | ariff <ariff@FreeBSD.org> | 2005-12-31 01:58:40 +0000 |
---|---|---|
committer | ariff <ariff@FreeBSD.org> | 2005-12-31 01:58:40 +0000 |
commit | deb09036e824eb9221944cd1227aeb23e23dda6c (patch) | |
tree | b1d4541477f6757255eed0cd45854941cc677acf /sys | |
parent | adbf28a0ed3867d492773181a1a7a51f2c4a9529 (diff) | |
download | FreeBSD-src-deb09036e824eb9221944cd1227aeb23e23dda6c.zip FreeBSD-src-deb09036e824eb9221944cd1227aeb23e23dda6c.tar.gz |
Fix LOR #174.
Tested with: WITNESS, INVARIANTS and DIAGNOSTICS
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 27fed2e..ecf97ef 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -248,11 +248,12 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) /* got a channel, already locked for us */ if (chn_reset(rdch, fmt)) { pcm_chnrelease(rdch); + pcm_lock(d); i_dev->si_drv1 = NULL; + pcm_unlock(d); return ENODEV; } - pcm_lock(d); if (flags & O_NONBLOCK) rdch->flags |= CHN_F_NBIO; pcm_chnref(rdch, 1); @@ -261,6 +262,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) /* * Record channel created, ref'ed and unlocked */ + pcm_lock(d); } if (flags & FWRITE) { @@ -274,14 +276,15 @@ 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) { /* * Free play channel */ pcm_chnrelease(wrch); + pcm_lock(d); i_dev->si_drv2 = NULL; + pcm_unlock(d); } if (rdref) { /* @@ -290,10 +293,11 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) CHN_LOCK(rdch); pcm_chnref(rdch, -1); pcm_chnrelease(rdch); + pcm_lock(d); i_dev->si_drv1 = NULL; + pcm_unlock(d); } - pcm_unlock(d); return error; } @@ -301,6 +305,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) wrch->flags |= CHN_F_NBIO; pcm_chnref(wrch, 1); CHN_UNLOCK(wrch); + pcm_lock(d); } i_dev->si_drv1 = rdch; @@ -318,8 +323,10 @@ dsp_close(struct cdev *i_dev, int flags, int mode, struct thread *td) int refs; d = dsp_get_info(i_dev); + pcm_lock(d); rdch = i_dev->si_drv1; wrch = i_dev->si_drv2; + pcm_unlock(d); refs = 0; |