diff options
author | Max Kellermann <max@duempel.org> | 2009-03-27 16:44:36 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-03-27 16:44:36 +0100 |
commit | 8258457b434fd24dba6025b474c2d3be8f8183d3 (patch) | |
tree | 74bd320f22862a931bc3b25e3e9a7fd429f8b53d /src/mixer/pulse_mixer.c | |
parent | 1a411b1cedfad5073fa545c852a6d23107a1ddd0 (diff) | |
download | mpd-8258457b434fd24dba6025b474c2d3be8f8183d3.tar.gz mpd-8258457b434fd24dba6025b474c2d3be8f8183d3.tar.xz mpd-8258457b434fd24dba6025b474c2d3be8f8183d3.zip |
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.
Diffstat (limited to 'src/mixer/pulse_mixer.c')
-rw-r--r-- | src/mixer/pulse_mixer.c | 35 |
1 files changed, 34 insertions, 1 deletions
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); |