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.
This commit is contained in:
parent
1a411b1ced
commit
8258457b43
@ -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
|
static void
|
||||||
sink_input_cb(G_GNUC_UNUSED pa_context *context, const pa_sink_input_info *i,
|
sink_input_cb(G_GNUC_UNUSED pa_context *context, const pa_sink_input_info *i,
|
||||||
int eol, void *userdata)
|
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);
|
g_debug("sink input vol %s, index %d ", i->name, i->index);
|
||||||
pm->volume = i->volume;
|
pm->volume = i->volume;
|
||||||
|
|
||||||
|
pa_threaded_mainloop_signal(pm->mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -292,7 +324,8 @@ pulse_mixer_get_volume(struct mixer *mixer)
|
|||||||
return false;
|
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);
|
ret = (int)((100*(pa_cvolume_avg(&pm->volume)+1))/PA_VOLUME_NORM);
|
||||||
g_debug("volume %d", ret);
|
g_debug("volume %d", ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user