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.
This commit is contained in:
Max Kellermann 2009-03-14 11:53:28 +01:00
parent 82963ee023
commit 7deade8577
3 changed files with 37 additions and 5 deletions

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}