From 8258457b434fd24dba6025b474c2d3be8f8183d3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 27 Mar 2009 16:44:36 +0100 Subject: pulse_mixer: wait for get_volume() operation to complete The pa_context_get_sink_input_info() function is asynchronous, and after it returns, libpulse does not guarantee that the operation has completed yet; in fact, it is not likely. Explicitly wait for the operation to complete. The code for the new pulse_wait_for_operation() function was inspired by mplayer and xine code. --- src/mixer/pulse_mixer.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/mixer/pulse_mixer.c') diff --git a/src/mixer/pulse_mixer.c b/src/mixer/pulse_mixer.c index 899ab5446..f9c90191e 100644 --- a/src/mixer/pulse_mixer.c +++ b/src/mixer/pulse_mixer.c @@ -45,6 +45,36 @@ struct pulse_mixer { }; +/** + * \brief waits for a pulseaudio operation to finish, frees it and + * unlocks the mainloop + * \param operation the operation to wait for + * \return true if operation has finished normally (DONE state), + * false otherwise + */ +static bool +pulse_wait_for_operation(struct pa_threaded_mainloop *mainloop, + struct pa_operation *operation) +{ + pa_operation_state_t state; + + assert(mainloop != NULL); + assert(operation != NULL); + + pa_threaded_mainloop_lock(mainloop); + + state = pa_operation_get_state(operation); + while (state == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait(mainloop); + state = pa_operation_get_state(operation); + } + + pa_operation_unref(operation); + pa_threaded_mainloop_unlock(mainloop); + + return state == PA_OPERATION_DONE; +} + static void sink_input_cb(G_GNUC_UNUSED pa_context *context, const pa_sink_input_info *i, int eol, void *userdata) @@ -91,6 +121,8 @@ sink_input_vol(G_GNUC_UNUSED pa_context *context, const pa_sink_input_info *i, g_debug("sink input vol %s, index %d ", i->name, i->index); pm->volume = i->volume; + + pa_threaded_mainloop_signal(pm->mainloop, 0); } static void @@ -292,7 +324,8 @@ pulse_mixer_get_volume(struct mixer *mixer) return false; } - pa_operation_unref(o); + if (!pulse_wait_for_operation(pm->mainloop, o)) + return false; ret = (int)((100*(pa_cvolume_avg(&pm->volume)+1))/PA_VOLUME_NORM); g_debug("volume %d", ret); -- cgit v1.2.3