Commit 7deade85 authored by Max Kellermann's avatar Max Kellermann

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.
parent 82963ee0
......@@ -19,8 +19,6 @@
#include "mixer_api.h"
#include <glib.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "mixer"
......@@ -28,4 +26,5 @@ void
mixer_init(struct mixer *mixer, const struct mixer_plugin *plugin)
{
mixer->plugin = plugin;
mixer->mutex = g_mutex_new();
}
......@@ -23,8 +23,16 @@
#include "mixer_plugin.h"
#include "mixer_list.h"
#include <glib.h>
struct mixer {
const struct mixer_plugin *plugin;
/**
* This mutex protects all of the mixer struct, including its
* implementation, so plugins don't have to deal with that.
*/
GMutex *mutex;
};
void
......
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment