diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2015-05-12 18:05:44 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2015-05-12 18:05:44 +0000 |
commit | 65be931cfcb21c0d6b6d2daad9053aa5f0bb9a04 (patch) | |
tree | 895c0b2707c0c1663012411c651f06982df11753 /sys/dev | |
parent | 0f9261cb26f71fa05f587479341d6b3ad8386e5b (diff) |
Don't hold the audio mutex when calling uiomove(), as uiomove()
may sleep in case of a page fault
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/midi.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/dev/midi.c b/sys/dev/midi.c index d2f00461b66..277682a932e 100644 --- a/sys/dev/midi.c +++ b/sys/dev/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.34 2015/03/14 03:38:46 jsg Exp $ */ +/* $OpenBSD: midi.c,v 1.35 2015/05/12 18:05:43 ratchov Exp $ */ /* * Copyright (c) 2003, 2004 Alexandre Ratchov @@ -141,11 +141,11 @@ midiread(dev_t dev, struct uio *uio, int ioflag) count = mb->used; if (count > uio->uio_resid) count = uio->uio_resid; + mtx_leave(&audio_lock); error = uiomovei(mb->data + mb->start, count, uio); - if (error) { - mtx_leave(&audio_lock); + if (error) return error; - } + mtx_enter(&audio_lock); MIDIBUF_REMOVE(mb, count); } mtx_leave(&audio_lock); @@ -246,12 +246,13 @@ midiwrite(dev_t dev, struct uio *uio, int ioflag) * in the buffer to store at least one byte. If not then dont * start the write process. */ - - if ((ioflag & IO_NDELAY) && MIDIBUF_ISFULL(mb) && (uio->uio_resid > 0)) + mtx_enter(&audio_lock); + if ((ioflag & IO_NDELAY) && MIDIBUF_ISFULL(mb) && (uio->uio_resid > 0)) { + mtx_leave(&audio_lock); return EWOULDBLOCK; + } while (uio->uio_resid > 0) { - mtx_enter(&audio_lock); while (MIDIBUF_ISFULL(mb)) { if (ioflag & IO_NDELAY) { /* @@ -279,15 +280,15 @@ midiwrite(dev_t dev, struct uio *uio, int ioflag) count = MIDIBUF_AVAIL(mb); if (count > uio->uio_resid) count = uio->uio_resid; + mtx_leave(&audio_lock); error = uiomovei(mb->data + MIDIBUF_END(mb), count, uio); - if (error) { - mtx_leave(&audio_lock); + if (error) return error; - } + mtx_enter(&audio_lock); mb->used += count; midi_out_start(sc); - mtx_leave(&audio_lock); } + mtx_leave(&audio_lock); return 0; } |