From 7133f560ec24c90671a40c9f9bc9cea6eb31cc17 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 14 Aug 2009 11:52:12 +0200 Subject: [PATCH] output: fixed shout stuck pause bug Explicitly make the output thread leave the ao_pause() loop. This patch is a workaround, and the "pause" flag is not managed in a thread-safe way, but that's good enough for now. --- NEWS | 2 ++ src/output_control.c | 11 +++++++++++ src/output_internal.h | 6 ++++++ src/output_thread.c | 3 +++ 4 files changed, 22 insertions(+) diff --git a/NEWS b/NEWS index d10ac66e7..e0f6a433d 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ ver 0.15.2 (2009/??/??) - mad: skip ID3 frames when libid3tag is disabled - flac: parse all replaygain tags - flac: don't allocate cuesheet twice (memleak) +* output: + - shout: fixed stuck pause bug * update: free empty path string (memleak) * update: free temporary string in container scan (memleak) * directory: free empty directories after removing them (memleak) diff --git a/src/output_control.c b/src/output_control.c index eac9bdfcb..16c0dbb75 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -76,6 +76,17 @@ audio_output_open(struct audio_output *ao, audio_format_equals(audio_format, &ao->in_audio_format)) { assert(ao->pipe == mp); + if (ao->pause) { + /* unpause with the CANCEL command; this is a + hack, but suits well for forcing the thread + to leave the ao_pause() thread, and we need + to flush the device buffer anyway */ + + /* we're not using audio_output_cancel() here, + because that function is asynchronous */ + ao_command(ao, AO_COMMAND_CANCEL); + } + return true; } diff --git a/src/output_internal.h b/src/output_internal.h index 362d24947..72596c1c3 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -80,6 +80,12 @@ struct audio_output { */ bool open; + /** + * Is the device paused? i.e. the output thread is in the + * ao_pause() loop. + */ + bool pause; + /** * If not NULL, the device has failed, and this timer is used * to estimate how long it should stay disabled (unless diff --git a/src/output_thread.c b/src/output_thread.c index d414ba8d5..785ac808f 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -165,6 +165,7 @@ static void ao_pause(struct audio_output *ao) bool ret; ao_plugin_cancel(ao->plugin, ao->data); + ao->pause = true; ao_command_finished(ao); do { @@ -174,6 +175,8 @@ static void ao_pause(struct audio_output *ao) break; } } while (ao->command == AO_COMMAND_NONE); + + ao->pause = false; } static gpointer audio_output_task(gpointer arg)