Permalink
Browse files

Track dlopen'd module pointers, dlclose on purge()

This adds remix_unload() functions to loaded modules, calls
plugin->destroy, and keeps a module pointer returned by dlopen() in
remix_plugin.c and remix_ladspa.c.

git-svn-id: http://svn.metadecks.org/libremix/trunk@712 e2d53364-18fc-0310-981e-b60a84739af0
  • Loading branch information...
1 parent 40df5da commit 00b3b29c3b10e03ca579d39cef34969f0a3200c3 conrad committed Apr 11, 2010
Showing with 55 additions and 8 deletions.
  1. +0 −3 TODO
  2. +4 −4 src/libremix/remix_context.c
  3. +36 −0 src/libremix/remix_plugin.c
  4. +1 −0 src/libremix/remix_private.h
  5. +14 −1 src/plugins/ladspa/remix_ladspa.c
View
3 TODO
@@ -13,7 +13,4 @@ libremix:
world->plugins and world->bases
ladspa:
- * implement plugin->destroy
- * keep module pointer returned by dlopen() in remix-ladspa.c, and
- call dlclose() on that from remix_purge().
* free schemes created for each ladspa port
@@ -47,11 +47,11 @@ remix_context_destroy (RemixEnv * env)
world->purging = 1;
- cd_list_apply (env, world->plugins, (CDFunc)remix_plugin_destroy);
- world->plugins = cd_list_free (env, world->plugins);
+ world->plugins = cd_list_destroy_with (env, world->plugins, remix_plugin_destroy);
+ remix_plugin_defaults_unload (env);
- /* XXX: remix_destroy_list (env, world->plugins); */
- /* XXX: remix_destroy_list (env, world->bases); */
+ /* TODO: remix_destroy_list (env, world->plugins); */
+ /* TODO: remix_destroy_list (env, world->bases); */
remix_channelset_defaults_destroy (env);
remix_free (ctx);
remix_free (world);
@@ -41,6 +41,8 @@
#define __REMIX__
#include "remix.h"
+static CDList * modules_list = CD_EMPTY_LIST;
+
static CDList *
remix_plugin_initialise_static (RemixEnv * env)
{
@@ -59,6 +61,7 @@ static CDList *
remix_plugin_init (RemixEnv * env, const char * path)
{
void * module;
+ CDList * l;
RemixPluginInitFunc init;
module = dlopen (path, RTLD_NOW);
@@ -70,6 +73,17 @@ remix_plugin_init (RemixEnv * env, const char * path)
return CD_EMPTY_LIST;
}
+ /* Check that this module has not already been loaded (eg. if it is
+ * a symlink etc.) */
+ for (l = modules_list; l; l = l->next) {
+ if (l->data.s_pointer == module) {
+ dlclose (module);
+ return CD_EMPTY_LIST;
+ }
+ }
+
+ modules_list = cd_list_append (env, modules_list, CD_POINTER(module));
+
if ((init = dlsym (module, "remix_load")) != NULL) {
return init (env);
}
@@ -130,6 +144,28 @@ remix_plugin_defaults_initialise (RemixEnv * env)
cd_list_apply (env, plugins, (CDFunc)_remix_register_plugin);
}
+static int
+remix_plugin_unload (RemixEnv * env, void * module)
+{
+ RemixPluginInitFunc unload; /* TODO: make new unload type */
+
+ if ((unload = dlsym (module, "remix_unload")) != NULL) {
+ unload (env);
+ }
+
+ dlclose (module);
+
+ return 0;
+}
+
+void
+remix_plugin_defaults_unload (RemixEnv * env)
+{
+ CDList * l;
+
+ modules_list = cd_list_destroy_with (env, modules_list, (CDDestroyFunc)remix_plugin_unload);
+}
+
#if 0
RemixPlugin
@@ -286,6 +286,7 @@ RemixEnv * _remix_unregister_base (RemixEnv * env, RemixBase * base);
/* remix_plugin */
void remix_plugin_defaults_initialise (RemixEnv * env);
+void remix_plugin_defaults_unload (RemixEnv * env);
/* remix_deck */
RemixTrack * _remix_deck_add_track (RemixEnv * env, RemixDeck * deck,
@@ -873,7 +873,7 @@ ladspa_wrapper_load_plugins (RemixEnv * env, char * dir, char * name)
RemixPlugin * plugin;
RemixMetaText * mt;
RemixParameterScheme * scheme;
- CDList * plugins = CD_EMPTY_LIST;
+ CDList * l, * plugins = CD_EMPTY_LIST;
#define BUF_LEN 256
static char buf[BUF_LEN];
struct stat statbuf;
@@ -886,6 +886,17 @@ ladspa_wrapper_load_plugins (RemixEnv * env, char * dir, char * name)
module = dlopen (path, RTLD_NOW);
if (!module) return CD_EMPTY_LIST;
+ /* Check that this module has not already been loaded (eg. if it is
+ * a symlink etc.) */
+ for (l = modules_list; l; l = l->next) {
+ if (l->data.s_pointer == module) {
+ dlclose (module);
+ return CD_EMPTY_LIST;
+ }
+ }
+
+ modules_list = cd_list_append (env, modules_list, CD_POINTER(module));
+
if ((desc_func = dlsym (module, "ladspa_descriptor"))) {
for (i=0; (d = desc_func (i)) != NULL; i++) {
@@ -1028,5 +1039,7 @@ remix_unload (RemixEnv * env)
for (l = modules_list; l; l = l->next) {
dlclose(l->data.s_pointer);
}
+
+ modules_list = NULL;
}

0 comments on commit 00b3b29

Please sign in to comment.