diff options
Diffstat (limited to 'src/pulsecore/module.c')
-rw-r--r-- | src/pulsecore/module.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index e6d7fcaf..f1eeb762 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -46,6 +44,7 @@ #define PA_SYMBOL_INIT "pa__init" #define PA_SYMBOL_DONE "pa__done" +#define PA_SYMBOL_LOAD_ONCE "pa__load_once" #define UNLOAD_POLL_TIME 2 @@ -66,6 +65,7 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { pa_module *m = NULL; + pa_bool_t (*load_once)(void); pa_assert(c); pa_assert(name); @@ -82,6 +82,22 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { goto fail; } + if ((load_once = (pa_bool_t (*)(void)) pa_load_sym(m->dl, name, PA_SYMBOL_LOAD_ONCE))) { + + if (load_once() && c->modules) { + pa_module *i; + uint32_t idx; + /* OK, the module only wants to be loaded once, let's make sure it is */ + + for (i = pa_idxset_first(c->modules, &idx); i; i = pa_idxset_next(c->modules, &idx)) { + if (strcmp(name, i->name) == 0) { + pa_log("Module \"%s\" should be loaded once at most. Refusing to load.", name); + goto fail; + } + } + } + } + if (!(m->init = (int (*)(pa_module*_m)) pa_load_sym(m->dl, name, PA_SYMBOL_INIT))) { pa_log("Failed to load module \"%s\": symbol \""PA_SYMBOL_INIT"\" not found.", name); goto fail; @@ -91,8 +107,8 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { m->userdata = NULL; m->core = c; m->n_used = -1; - m->auto_unload = 0; - m->unload_requested = 0; + m->auto_unload = FALSE; + m->unload_requested = FALSE; if (m->init(m) < 0) { pa_log_error("Failed to load module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : ""); @@ -102,7 +118,7 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { if (!c->modules) c->modules = pa_idxset_new(NULL, NULL); - if (!c->module_auto_unload_event) { + if (m->auto_unload && !c->module_auto_unload_event) { struct timeval ntv; pa_gettimeofday(&ntv); pa_timeval_add(&ntv, UNLOAD_POLL_TIME*1000000); @@ -186,7 +202,7 @@ static void free_callback(void *p, PA_GCC_UNUSED void *userdata) { void pa_module_unload_all(pa_core *c) { pa_module *m; - + pa_assert(c); if (!c->modules) @@ -212,7 +228,7 @@ void pa_module_unload_all(pa_core *c) { static int unused_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void *userdata) { pa_module *m = p; time_t *now = userdata; - + pa_assert(m); pa_assert(del); pa_assert(now); @@ -263,7 +279,7 @@ static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) { void pa_module_unload_request(pa_module *m) { pa_assert(m); - m->unload_requested = 1; + m->unload_requested = TRUE; if (!m->core->module_defer_unload_event) m->core->module_defer_unload_event = m->core->mainloop->defer_new(m->core->mainloop, defer_cb, m->core); |