aboutsummaryrefslogtreecommitdiff
path: root/src/output_control.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-10-29 22:39:42 +0100
committerMax Kellermann <max@duempel.org>2009-10-29 22:39:42 +0100
commit975143ab474a020723f333e2dd7bb064038623d4 (patch)
tree43384063c16726ab4878d6e252bccd4c7984bbd8 /src/output_control.c
parentbb5acc939fccd27c5ac47173905dcdf84f88a722 (diff)
output_control: fixed deadlock in audio_output_update()
Call a version of audio_output_close() which doesn't lock recursively.
Diffstat (limited to 'src/output_control.c')
-rw-r--r--src/output_control.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/output_control.c b/src/output_control.c
index 46d8f869..973baa46 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;