From 21223154aa3a3c794a3842aa8a5c85198ce85220 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 4 Nov 2010 21:51:02 +0100 Subject: output_control: lock object in audio_output_close() Protect the attributes "open" and "fail_timer". --- src/output_control.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/output_control.c b/src/output_control.c index 16c0dbb75..dd562f303 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -50,6 +50,20 @@ static void ao_command(struct audio_output *ao, enum audio_output_command cmd) 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, enum audio_output_command cmd) { @@ -162,21 +176,33 @@ void audio_output_cancel(struct audio_output *ao) 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); if (ao->mixer != NULL) mixer_auto_close(ao->mixer); if (ao->open) - ao_command(ao, AO_COMMAND_CLOSE); + ao_command_locked(ao, AO_COMMAND_CLOSE); else if (ao->fail_timer != NULL) { g_timer_destroy(ao->fail_timer); 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) { audio_output_close(ao); -- cgit v1.2.3