diff options
author | Max Kellermann <max@duempel.org> | 2011-08-23 22:43:08 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2011-08-23 23:02:13 +0200 |
commit | b3df4dc2c92d27034eaf9cef52e97a6e39c77d2e (patch) | |
tree | 6a372b5331f6ed6402e1d2d2fd4ca07af780ddc9 /src/output/pulse_output_plugin.c | |
parent | 3db9ab82ea792fbfa398d0d631f976fa33a564fe (diff) | |
download | mpd-b3df4dc2c92d27034eaf9cef52e97a6e39c77d2e.tar.gz mpd-b3df4dc2c92d27034eaf9cef52e97a6e39c77d2e.tar.xz mpd-b3df4dc2c92d27034eaf9cef52e97a6e39c77d2e.zip |
output/pulse: fix deadlock when the stream was suspended
Check if the stream is suspended; wake up the main loop when it
becomes suspended.
Diffstat (limited to '')
-rw-r--r-- | src/output/pulse_output_plugin.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/output/pulse_output_plugin.c b/src/output/pulse_output_plugin.c index c0633b9fb..babb8e221 100644 --- a/src/output/pulse_output_plugin.c +++ b/src/output/pulse_output_plugin.c @@ -412,6 +412,23 @@ pulse_output_wait_connection(struct pulse_output *po, GError **error_r) } } +#if PA_CHECK_VERSION(0,9,8) + +static void +pulse_output_stream_suspended_cb(G_GNUC_UNUSED pa_stream *stream, void *userdata) +{ + struct pulse_output *po = userdata; + + assert(stream == po->stream || po->stream == NULL); + assert(po->mainloop != NULL); + + /* wake up the main loop to break out of the loop in + pulse_output_play() */ + pa_threaded_mainloop_signal(po->mainloop, 0); +} + +#endif + static void pulse_output_stream_state_cb(pa_stream *stream, void *userdata) { @@ -508,6 +525,11 @@ pulse_output_open(void *data, struct audio_format *audio_format, return false; } +#if PA_CHECK_VERSION(0,9,8) + pa_stream_set_suspended_callback(po->stream, + pulse_output_stream_suspended_cb, po); +#endif + pa_stream_set_state_callback(po->stream, pulse_output_stream_state_cb, po); pa_stream_set_write_callback(po->stream, @@ -719,6 +741,15 @@ pulse_output_play(void *data, const void *chunk, size_t size, GError **error_r) /* wait until the server allows us to write */ while (po->writable == 0) { +#if PA_CHECK_VERSION(0,9,8) + if (pa_stream_is_suspended(po->stream)) { + pa_threaded_mainloop_unlock(po->mainloop); + g_set_error(error_r, pulse_output_quark(), 0, + "suspended"); + return 0; + } +#endif + pa_threaded_mainloop_wait(po->mainloop); if (pa_stream_get_state(po->stream) != PA_STREAM_READY) { |