aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-10-29 23:35:27 +0100
committerMax Kellermann <max@duempel.org>2009-10-29 23:35:27 +0100
commitcec019efffe4ebb87ec2c630003e6bce5083bb5e (patch)
tree1494ffa760562639ac0df6d8eba8f4c17e764271 /src
parent4748decd8df52f747605271fac18f94437b78e0c (diff)
downloadmpd-cec019efffe4ebb87ec2c630003e6bce5083bb5e.tar.gz
mpd-cec019efffe4ebb87ec2c630003e6bce5083bb5e.tar.xz
mpd-cec019efffe4ebb87ec2c630003e6bce5083bb5e.zip
output_thread: return bool from ao_play()
Return false when there was no chunk in the pipe. If the function returns true, then audio_output_task() will not wait for a notify from the player thread. This fixes a race condition.
Diffstat (limited to '')
-rw-r--r--src/output_thread.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/output_thread.c b/src/output_thread.c
index af908cac5..24a22f6df 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -312,7 +312,16 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
return true;
}
-static void ao_play(struct audio_output *ao)
+/**
+ * Plays all remaining chunks, until the tail of the pipe has been
+ * reached (and no more chunks are queued), or until a command is
+ * received.
+ *
+ * @return true if at least one chunk has been available, false if the
+ * tail of the pipe was already reached
+ */
+static bool
+ao_play(struct audio_output *ao)
{
bool success;
const struct music_chunk *chunk;
@@ -323,8 +332,13 @@ static void ao_play(struct audio_output *ao)
if (chunk != NULL)
/* continue the previous play() call */
chunk = chunk->next;
- else
+ else {
chunk = music_pipe_peek(ao->pipe);
+ if (chunk == NULL)
+ /* no chunk available */
+ return false;
+ }
+
ao->chunk_finished = false;
while (chunk != NULL && ao->command == AO_COMMAND_NONE) {
@@ -347,6 +361,8 @@ static void ao_play(struct audio_output *ao)
g_mutex_unlock(ao->mutex);
notify_signal(&pc.notify);
g_mutex_lock(ao->mutex);
+
+ return true;
}
static void ao_pause(struct audio_output *ao)
@@ -440,8 +456,10 @@ static gpointer audio_output_task(gpointer arg)
return NULL;
}
- if (ao->open)
- ao_play(ao);
+ if (ao->open && ao_play(ao))
+ /* don't wait for an event if there are more
+ chunks in the pipe */
+ continue;
if (ao->command == AO_COMMAND_NONE)
g_cond_wait(ao->cond, ao->mutex);