summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lilv_internal.h15
-rw-r--r--src/plugin.c50
-rw-r--r--src/world.c26
3 files changed, 51 insertions, 40 deletions
diff --git a/src/lilv_internal.h b/src/lilv_internal.h
index 155cec8..c53eacb 100644
--- a/src/lilv_internal.h
+++ b/src/lilv_internal.h
@@ -83,12 +83,23 @@ struct LilvHeader {
LilvNode* uri;
};
+#ifdef LILV_DYN_MANIFEST
+typedef struct {
+ LilvNode* uri;
+ void* lib;
+ LV2_Dyn_Manifest_Handle handle;
+ uint32_t refs;
+} LilvDynManifest;
+#endif
+
struct LilvPluginImpl {
LilvWorld* world;
LilvNode* plugin_uri;
LilvNode* bundle_uri; ///< Bundle plugin was loaded from
LilvNode* binary_uri; ///< lv2:binary
- LilvNode* dynman_uri; ///< dynamic manifest binary
+#ifdef LILV_DYN_MANIFEST
+ LilvDynManifest* dynmanifest;
+#endif
const LilvPluginClass* plugin_class;
LilvNodes* data_uris; ///< rdfs::seeAlso
LilvPort** ports;
@@ -176,7 +187,7 @@ struct LilvScalePointImpl {
};
struct LilvUIImpl {
- LilvWorld* world;
+ LilvWorld* world;
LilvNode* uri;
LilvNode* bundle_uri;
LilvNode* binary_uri;
diff --git a/src/plugin.c b/src/plugin.c
index 88732d1..f4f1315 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -39,7 +39,7 @@ lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri)
plugin->bundle_uri = bundle_uri;
plugin->binary_uri = NULL;
#ifdef LILV_DYN_MANIFEST
- plugin->dynman_uri = NULL;
+ plugin->dynmanifest = NULL;
#endif
plugin->plugin_class = NULL;
plugin->data_uris = lilv_nodes_new();
@@ -54,6 +54,21 @@ lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri)
void
lilv_plugin_free(LilvPlugin* p)
{
+#ifdef LILV_DYN_MANIFEST
+ if (p->dynmanifest && --p->dynmanifest->refs == 0) {
+ typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle);
+ CloseFunc close_func = (CloseFunc)lilv_dlfunc(p->dynmanifest->lib,
+ "lv2_dyn_manifest_close");
+ if (close_func) {
+ close_func(p->dynmanifest->handle);
+ }
+
+ dlclose(p->dynmanifest->lib);
+ lilv_node_free(p->dynmanifest->uri);
+ free(p->dynmanifest);
+ }
+#endif
+
lilv_node_free(p->plugin_uri);
p->plugin_uri = NULL;
@@ -63,11 +78,6 @@ lilv_plugin_free(LilvPlugin* p)
lilv_node_free(p->binary_uri);
p->binary_uri = NULL;
-#ifdef LILV_DYN_MANIFEST
- lilv_node_free(p->dynman_uri);
- p->dynman_uri = NULL;
-#endif
-
if (p->ports) {
for (uint32_t i = 0; i < p->num_ports; ++i) {
lilv_port_free(p, p->ports[i]);
@@ -136,41 +146,23 @@ lilv_plugin_load(LilvPlugin* p)
#ifdef LILV_DYN_MANIFEST
typedef void* LV2_Dyn_Manifest_Handle;
// Load and parse dynamic manifest data, if this is a library
- if (p->dynman_uri) {
- const char* lib_path = lilv_uri_to_path(lilv_node_as_string(p->dynman_uri));
- void* lib = dlopen(lib_path, RTLD_LAZY);
- if (!lib) {
- LILV_WARNF("Failed to open dynamic manifest %s\n",
- lilv_node_as_string(p->dynman_uri));
- return;
- }
-
- typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, const LV2_Feature *const *);
- OpenFunc open_func = (OpenFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_open");
- LV2_Dyn_Manifest_Handle handle = NULL;
- if (open_func)
- open_func(&handle, &dman_features);
-
+ if (p->dynmanifest) {
typedef int (*GetDataFunc)(LV2_Dyn_Manifest_Handle handle,
FILE* fp,
const char* uri);
GetDataFunc get_data_func = (GetDataFunc)lilv_dlfunc(
- lib, "lv2_dyn_manifest_get_data");
+ p->dynmanifest->lib, "lv2_dyn_manifest_get_data");
if (get_data_func) {
serd_env_set_base_uri(
- env, sord_node_to_serd_node(p->dynman_uri->val.uri_val));
+ env, sord_node_to_serd_node(p->dynmanifest->uri->val.uri_val));
FILE* fd = tmpfile();
- get_data_func(handle, fd, lilv_node_as_string(p->plugin_uri));
+ get_data_func(p->dynmanifest->handle, fd,
+ lilv_node_as_string(p->plugin_uri));
rewind(fd);
serd_reader_read_file_handle(reader, fd,
(const uint8_t*)"(dyn-manifest)");
fclose(fd);
}
-
- typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle);
- CloseFunc close_func = (CloseFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_close");
- if (close_func)
- close_func(handle);
}
#endif
serd_reader_free(reader);
diff --git a/src/world.c b/src/world.c
index e291c55..ba75ec8 100644
--- a/src/world.c
+++ b/src/world.c
@@ -328,11 +328,11 @@ lilv_world_add_spec(LilvWorld* world,
}
static void
-lilv_world_add_plugin(LilvWorld* world,
- const SordNode* plugin_node,
- SerdNode* manifest_uri,
- const SordNode* dyn_manifest_lib,
- const SordNode* bundle_node)
+lilv_world_add_plugin(LilvWorld* world,
+ const SordNode* plugin_node,
+ SerdNode* manifest_uri,
+ void* dynmanifest,
+ const SordNode* bundle_node)
{
LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node);
@@ -355,10 +355,13 @@ lilv_world_add_plugin(LilvWorld* world,
lilv_new_uri(world, (const char*)manifest_uri->buf),
NULL);
+#ifdef LILV_DYN_MANIFEST
// Set dynamic manifest library URI, if applicable
- if (dyn_manifest_lib) {
- plugin->dynman_uri = lilv_node_new_from_node(world, dyn_manifest_lib);
+ if (dynmanifest) {
+ plugin->dynmanifest = (LilvDynManifest*)dynmanifest;
+ ++((LilvDynManifest*)dynmanifest)->refs;
}
+#endif
// Add all plugin data files (rdfs:seeAlso)
SordIter* files = lilv_world_find_statements(
@@ -456,6 +459,12 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
continue;
}
+ LilvDynManifest* desc = malloc(sizeof(LilvDynManifest));
+ desc->uri = lilv_node_new_from_node(world, dmanifest);
+ desc->lib = lib;
+ desc->handle = handle;
+ desc->refs = 0;
+
// Generate data file
FILE* fd = tmpfile();
get_subjects_func(handle, fd);
@@ -483,12 +492,11 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
FOREACH_MATCH(plug_results) {
const SordNode* plugin_node = lilv_match_subject(plug_results);
lilv_world_add_plugin(world, plugin_node,
- &manifest_uri, binary, bundle_node);
+ &manifest_uri, desc, bundle_node);
}
lilv_match_end(plug_results);
lilv_match_end(binaries);
- dlclose(lib);
}
lilv_match_end(dmanifests);
#endif // LILV_DYN_MANIFEST