Fix some of the places where sound(4) can sleep with a lock held. (Help

courtesy of fenner).
This commit is contained in:
Brian Feldman 2002-07-25 04:49:45 +00:00
parent 8625e3721f
commit ca33ae2367
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=100654
3 changed files with 32 additions and 14 deletions

View File

@ -300,7 +300,9 @@ sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS)
m = oidp->oid_arg1;
snd_mtxlock(m->lock);
strncpy(devname, snd_mixernames[m->hwvol_mixer], sizeof(devname));
snd_mtxunlock(m->lock);
error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req);
snd_mtxlock(m->lock);
if (error == 0 && req->newptr != NULL) {
dev = mixer_lookup(devname);
if (dev == -1) {

View File

@ -112,7 +112,7 @@ static int
sndstat_open(dev_t i_dev, int flags, int mode, struct thread *td)
{
intrmask_t s;
int err;
int error;
s = spltty();
mtx_lock(&sndstat_lock);
@ -121,19 +121,24 @@ sndstat_open(dev_t i_dev, int flags, int mode, struct thread *td)
splx(s);
return EBUSY;
}
if (sbuf_new(&sndstat_sbuf, NULL, 4096, 0) == NULL) {
mtx_unlock(&sndstat_lock);
splx(s);
return ENXIO;
}
sndstat_bufptr = 0;
err = (sndstat_prepare(&sndstat_sbuf) > 0)? 0 : ENOMEM;
if (!err)
sndstat_isopen = 1;
sndstat_isopen = 1;
mtx_unlock(&sndstat_lock);
splx(s);
return err;
if (sbuf_new(&sndstat_sbuf, NULL, 4096, 0) == NULL) {
error = ENXIO;
goto out;
}
sndstat_bufptr = 0;
error = (sndstat_prepare(&sndstat_sbuf) > 0) ? 0 : ENOMEM;
out:
if (error) {
s = spltty();
mtx_lock(&sndstat_lock);
sndstat_isopen = 0;
mtx_unlock(&sndstat_lock);
splx(s);
}
return (error);
}
static int

View File

@ -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);