diff options
author | Max Kellermann <max@duempel.org> | 2009-10-29 22:39:42 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-10-29 22:39:42 +0100 |
commit | 975143ab474a020723f333e2dd7bb064038623d4 (patch) | |
tree | 43384063c16726ab4878d6e252bccd4c7984bbd8 /src | |
parent | bb5acc939fccd27c5ac47173905dcdf84f88a722 (diff) | |
download | mpd-975143ab474a020723f333e2dd7bb064038623d4.tar.gz mpd-975143ab474a020723f333e2dd7bb064038623d4.tar.xz mpd-975143ab474a020723f333e2dd7bb064038623d4.zip |
output_control: fixed deadlock in audio_output_update()
Call a version of audio_output_close() which doesn't lock recursively.
Diffstat (limited to 'src')
-rw-r--r-- | src/output_control.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/output_control.c b/src/output_control.c index 46d8f8696..973baa463 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -157,6 +157,26 @@ audio_output_open(struct audio_output *ao, return open; } +/** + * Same as audio_output_close(), but expects the lock to be held by + * the caller. + */ +static void +audio_output_close_locked(struct audio_output *ao) +{ + if (ao->mixer != NULL) + mixer_auto_close(ao->mixer); + + assert(!ao->open || ao->fail_timer == NULL); + + if (ao->open) + ao_command(ao, AO_COMMAND_CLOSE); + else if (ao->fail_timer != NULL) { + g_timer_destroy(ao->fail_timer); + ao->fail_timer = NULL; + } +} + bool audio_output_update(struct audio_output *ao, const struct audio_format *audio_format, @@ -174,7 +194,7 @@ audio_output_update(struct audio_output *ao, return success; } } else if (audio_output_is_open(ao)) - audio_output_close(ao); + audio_output_close_locked(ao); g_mutex_unlock(ao->mutex); return false; |