aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-03-27 16:44:31 +0100
committerMax Kellermann <max@duempel.org>2009-03-27 16:44:31 +0100
commit1a411b1cedfad5073fa545c852a6d23107a1ddd0 (patch)
tree59911cf5859f92977f44b3073278727a91e732ff
parente7519829ac588e4b261c1832bb0e7d6ffbd47322 (diff)
downloadmpd-1a411b1cedfad5073fa545c852a6d23107a1ddd0.tar.gz
mpd-1a411b1cedfad5073fa545c852a6d23107a1ddd0.tar.xz
mpd-1a411b1cedfad5073fa545c852a6d23107a1ddd0.zip
mixer_control: don't lock the mutex twice in mixer_failed()
The function mixer_failed() expects the mixer mutex to be already locked, yet it calls mixer_close(), which attempts to lock the mutex again, deadlocking itself.
-rw-r--r--src/mixer_control.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/mixer_control.c b/src/mixer_control.c
index 908de5c54..9c361e5da 100644
--- a/src/mixer_control.c
+++ b/src/mixer_control.c
@@ -89,6 +89,17 @@ mixer_open(struct mixer *mixer)
return success;
}
+static void
+mixer_close_internal(struct mixer *mixer)
+{
+ assert(mixer != NULL);
+ assert(mixer->plugin != NULL);
+ assert(mixer->open);
+
+ mixer->plugin->close(mixer);
+ mixer->open = false;
+}
+
void
mixer_close(struct mixer *mixer)
{
@@ -97,10 +108,8 @@ mixer_close(struct mixer *mixer)
g_mutex_lock(mixer->mutex);
- if (mixer->open) {
- mixer->plugin->close(mixer);
- mixer->open = false;
- }
+ if (mixer->open)
+ mixer_close_internal(mixer);
g_mutex_unlock(mixer->mutex);
}
@@ -121,7 +130,7 @@ mixer_failed(struct mixer *mixer)
{
assert(mixer->open);
- mixer_close(mixer);
+ mixer_close_internal(mixer);
mixer->failed = true;
}