summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-08-14 11:52:12 +0200
committerMax Kellermann <max@duempel.org>2009-08-14 11:52:12 +0200
commit7133f560ec24c90671a40c9f9bc9cea6eb31cc17 (patch)
tree09d34f30a6173ff58afe37ece71bcaaca5d4423f
parent7dddd9beda2bb0505758bb6a32cae6feb3215733 (diff)
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.
-rw-r--r--NEWS2
-rw-r--r--src/output_control.c11
-rw-r--r--src/output_internal.h6
-rw-r--r--src/output_thread.c3
4 files changed, 22 insertions, 0 deletions
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
@@ -81,6 +81,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
* explicitly reopened with "play").
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)