diff options
author | green <green@FreeBSD.org> | 2002-07-25 04:49:45 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2002-07-25 04:49:45 +0000 |
commit | de2cfb0a7a345b657b83e8a56d35a723fc436192 (patch) | |
tree | 5c72f4c9c3de7b3c307d1b3e261f39f93e56ad6a /sys/dev/sound/pcm/sound.c | |
parent | 891c9fcb896ad87afa576f252cb60c125f96ac38 (diff) | |
download | FreeBSD-src-de2cfb0a7a345b657b83e8a56d35a723fc436192.zip FreeBSD-src-de2cfb0a7a345b657b83e8a56d35a723fc436192.tar.gz |
Fix some of the places where sound(4) can sleep with a lock held. (Help
courtesy of fenner).
Diffstat (limited to 'sys/dev/sound/pcm/sound.c')
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 3f346f3..8fe48a2 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -798,7 +798,7 @@ sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) struct snddev_info *d; struct snddev_channel *sce; struct pcm_channel *c; - int err, oldcnt, newcnt, cnt; + int err, newcnt, cnt; d = oidp->oid_arg1; @@ -809,10 +809,21 @@ sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) cnt++; } - oldcnt = cnt; newcnt = cnt; + pcm_unlock(d); err = sysctl_handle_int(oidp, &newcnt, sizeof(newcnt), req); + pcm_lock(d); + /* + * Since we dropped the pcm_lock, reload cnt now as it may + * have changed. + */ + cnt = 0; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) + cnt++; + } if (err == 0 && req->newptr != NULL) { if (newcnt < 0 || newcnt > SND_MAXVCHANS) { pcm_unlock(d); |