From 7deade857733e2a38d2da926acfc69b235fa4d0f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 14 Mar 2009 11:53:28 +0100 Subject: mixer: protect the mixer struct with a mutex In some rare cases, there was a race condition between the output thread and the main thread: when you disable/enable an output device in the main thread, this caused a crash in the output thread. Protect the whole mixer struct with a GMutex to prevent that. --- src/mixer_control.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'src/mixer_control.c') diff --git a/src/mixer_control.c b/src/mixer_control.c index ba49e2ec4..d3f246800 100644 --- a/src/mixer_control.c +++ b/src/mixer_control.c @@ -62,6 +62,9 @@ mixer_free(struct mixer *mixer) return; } assert(mixer->plugin != NULL); + assert(mixer->mutex != NULL); + + g_mutex_free(mixer->mutex); mixer->plugin->finish(mixer); } @@ -69,11 +72,18 @@ mixer_free(struct mixer *mixer) bool mixer_open(struct mixer *mixer) { + bool success; + if (!mixer) { return false; } assert(mixer->plugin != NULL); - return mixer->plugin->open(mixer); + + g_mutex_lock(mixer->mutex); + success = mixer->plugin->open(mixer); + g_mutex_unlock(mixer->mutex); + + return success; } void @@ -83,17 +93,32 @@ mixer_close(struct mixer *mixer) return; } assert(mixer->plugin != NULL); + + g_mutex_lock(mixer->mutex); mixer->plugin->close(mixer); + g_mutex_unlock(mixer->mutex); } int mixer_get_volume(struct mixer *mixer) { - return mixer->plugin->get_volume(mixer); + int volume; + + g_mutex_lock(mixer->mutex); + volume = mixer->plugin->get_volume(mixer); + g_mutex_unlock(mixer->mutex); + + return volume; } bool mixer_set_volume(struct mixer *mixer, unsigned volume) { - return mixer->plugin->set_volume(mixer, volume); + bool success; + + g_mutex_lock(mixer->mutex); + success = mixer->plugin->set_volume(mixer, volume); + g_mutex_unlock(mixer->mutex); + + return success; } -- cgit v1.2.3