diff options
author | Max Kellermann <max@duempel.org> | 2010-11-04 21:51:02 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2010-11-04 21:51:02 +0100 |
commit | 21223154aa3a3c794a3842aa8a5c85198ce85220 (patch) | |
tree | 54d29e4ea9a639c33915a64d92809455dfe96094 /src | |
parent | a549d871f30db65da597b6d9b478dd5bab1a62f9 (diff) | |
download | mpd-21223154aa3a3c794a3842aa8a5c85198ce85220.tar.gz mpd-21223154aa3a3c794a3842aa8a5c85198ce85220.tar.xz mpd-21223154aa3a3c794a3842aa8a5c85198ce85220.zip |
output_control: lock object in audio_output_close()
Protect the attributes "open" and "fail_timer".
Diffstat (limited to '')
-rw-r--r-- | src/output_control.c | 30 |
1 files changed, 28 insertions, 2 deletions
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); |