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:
parent
82963ee023
commit
7deade8577
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user