diff options
author | Max Kellermann <max@duempel.org> | 2009-08-13 23:33:46 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-08-13 23:33:46 +0200 |
commit | e28a0e97b5d2e54684c6452d6d45f64ff1e542d9 (patch) | |
tree | 38f0c66be040d13c8356293e64cedf8280174fbc /src/decoder_internal.c | |
parent | 499ed62dd790949c571517b54ef0e96fad26b16b (diff) | |
download | mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.gz mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.xz mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.zip |
decoder_control: protect command, state with a mutex
Replace decoder_control.notify with decoder_control.mutex and
decoder_control.cond. Lock the mutex on all accesses to
decoder_control.command and decoder_control.state.
Diffstat (limited to 'src/decoder_internal.c')
-rw-r--r-- | src/decoder_internal.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/decoder_internal.c b/src/decoder_internal.c index 4a56fa5f3..1b064d0aa 100644 --- a/src/decoder_internal.c +++ b/src/decoder_internal.c @@ -28,6 +28,24 @@ #include <assert.h> /** + * This is a wrapper for input_stream_buffer(). It assumes that the + * decoder is currently locked, and temporarily unlocks it while + * calling input_stream_buffer(). We shouldn't hold the lock during a + * potentially blocking operation. + */ +static int +decoder_input_buffer(struct input_stream *is) +{ + int ret; + + decoder_unlock(); + ret = input_stream_buffer(is) > 0; + decoder_lock(); + + return ret; +} + +/** * All chunks are full of decoded data; wait for the player to free * one. */ @@ -38,9 +56,12 @@ need_chunks(struct input_stream *is, bool do_wait) dc.command == DECODE_COMMAND_SEEK) return dc.command; - if ((is == NULL || input_stream_buffer(is) <= 0) && do_wait) { - notify_wait(&dc.notify); + if ((is == NULL || decoder_input_buffer(is) <= 0) && do_wait) { + decoder_wait(); + + decoder_unlock(); notify_signal(&pc.notify); + decoder_lock(); return dc.command; } @@ -63,7 +84,9 @@ decoder_get_chunk(struct decoder *decoder, struct input_stream *is) if (decoder->chunk != NULL) return decoder->chunk; + decoder_lock(); cmd = need_chunks(is, true); + decoder_unlock(); } while (cmd == DECODE_COMMAND_NONE); return NULL; |