From e28a0e97b5d2e54684c6452d6d45f64ff1e542d9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 13 Aug 2009 23:33:46 +0200 Subject: 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. --- src/decoder_internal.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/decoder_internal.c') 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 @@ -27,6 +27,24 @@ #include +/** + * 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; -- cgit v1.2.3