output_control: lock object in audio_output_close()

Protect the attributes "open" and "fail_timer".
This commit is contained in:
Max Kellermann 2010-11-04 21:51:02 +01:00
parent a549d871f3
commit 21223154aa
1 changed files with 28 additions and 2 deletions

View File

@ -50,6 +50,20 @@ static void ao_command(struct audio_output *ao, enum audio_output_command cmd)
ao_command_wait(ao); ao_command_wait(ao);
} }
/**
* Like ao_command(), but assumes the object is locked by the caller.
*/
static void
ao_command_locked(struct audio_output *ao, enum audio_output_command cmd)
{
assert(ao->command == AO_COMMAND_NONE);
ao->command = cmd;
g_mutex_unlock(ao->mutex);
ao_command_wait(ao);
g_mutex_lock(ao->mutex);
}
static void ao_command_async(struct audio_output *ao, static void ao_command_async(struct audio_output *ao,
enum audio_output_command cmd) enum audio_output_command cmd)
{ {
@ -162,21 +176,33 @@ void audio_output_cancel(struct audio_output *ao)
ao_command_async(ao, AO_COMMAND_CANCEL); ao_command_async(ao, AO_COMMAND_CANCEL);
} }
void audio_output_close(struct audio_output *ao) static void
audio_output_close_locked(struct audio_output *ao)
{ {
assert(ao != NULL);
assert(!ao->open || ao->fail_timer == NULL); assert(!ao->open || ao->fail_timer == NULL);
if (ao->mixer != NULL) if (ao->mixer != NULL)
mixer_auto_close(ao->mixer); mixer_auto_close(ao->mixer);
if (ao->open) if (ao->open)
ao_command(ao, AO_COMMAND_CLOSE); ao_command_locked(ao, AO_COMMAND_CLOSE);
else if (ao->fail_timer != NULL) { else if (ao->fail_timer != NULL) {
g_timer_destroy(ao->fail_timer); g_timer_destroy(ao->fail_timer);
ao->fail_timer = NULL; ao->fail_timer = NULL;
} }
} }
void audio_output_close(struct audio_output *ao)
{
assert(ao != NULL);
assert(!ao->open || ao->fail_timer == NULL);
g_mutex_lock(ao->mutex);
audio_output_close_locked(ao);
g_mutex_unlock(ao->mutex);
}
void audio_output_finish(struct audio_output *ao) void audio_output_finish(struct audio_output *ao)
{ {
audio_output_close(ao); audio_output_close(ao);