diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | src/lib.c | 8 | ||||
-rw-r--r-- | src/lilv_internal.h | 2 | ||||
-rw-r--r-- | src/world.c | 20 |
4 files changed, 29 insertions, 5 deletions
@@ -3,8 +3,10 @@ lilv (0.18.1) unstable; * Don't load files multiple times if they are listed as rdfs:seeAlso for several plugins * Fix minor memory leak in test suite + * Call lv2_lib_descriptor separately for different bundle paths + (fix loading several dynamic plugins like Ingen at once) - -- David Robillard <d@drobilla.net> Fri, 17 Jan 2014 18:11:25 -0500 + -- David Robillard <d@drobilla.net> Fri, 17 Jan 2014 20:34:10 -0500 lilv (0.18.0) stable; @@ -22,8 +22,10 @@ lilv_lib_open(LilvWorld* world, const char* bundle_path, const LV2_Feature*const* features) { - ZixTreeIter* i = NULL; - const struct LilvHeader key = { world, (LilvNode*)uri }; + ZixTreeIter* i = NULL; + const LilvLib key = { + world, (LilvNode*)uri, (char*)bundle_path, NULL, NULL, NULL, 0 + }; if (!zix_tree_find(world->libs, &key, &i)) { LilvLib* llib = (LilvLib*)zix_tree_get(i); ++llib->refs; @@ -69,6 +71,7 @@ lilv_lib_open(LilvWorld* world, LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib)); llib->world = world; llib->uri = lilv_node_duplicate(uri); + llib->bundle_path = lilv_strdup(bundle_path); llib->lib = lib; llib->lv2_descriptor = df; #ifdef LILV_NEW_LV2 @@ -106,6 +109,7 @@ lilv_lib_close(LilvLib* lib) } lilv_node_free(lib->uri); + free(lib->bundle_path); free(lib); } } diff --git a/src/lilv_internal.h b/src/lilv_internal.h index ae58e04..ff68070 100644 --- a/src/lilv_internal.h +++ b/src/lilv_internal.h @@ -99,6 +99,7 @@ typedef struct { typedef struct { LilvWorld* world; LilvNode* uri; + char* bundle_path; void* lib; LV2_Descriptor_Function lv2_descriptor; #ifdef LILV_NEW_LV2 @@ -298,6 +299,7 @@ LilvNode* lilv_node_new_from_node(LilvWorld* world, const SordNode* lilv_node_as_node(const LilvNode* value); int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data); +int lilv_lib_compare(const void* a, const void* b, void* user_data); int lilv_ptr_cmp(const void* a, const void* b, void* user_data); diff --git a/src/world.c b/src/world.c index e6fcc47..7921a71 100644 --- a/src/world.c +++ b/src/world.c @@ -44,8 +44,7 @@ lilv_world_new(void) false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free); #ifdef LILV_NEW_LV2 - world->libs = zix_tree_new( - false, lilv_header_compare_by_uri, NULL, NULL); + world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL); #endif #define NS_DCTERMS "http://purl.org/dc/terms/" @@ -292,6 +291,23 @@ lilv_header_compare_by_uri(const void* a, const void* b, void* user_data) lilv_node_as_uri(header_b->uri)); } +/** + Comparator for libraries (world->libs). + + Libraries do have a LilvHeader, but we must also compare the bundle to + handle the case where the same library is loaded with different bundles, and + consequently different contents (mainly plugins). + */ +int +lilv_lib_compare(const void* a, const void* b, void* user_data) +{ + const LilvLib* const lib_a = (const LilvLib*)a; + const LilvLib* const lib_b = (const LilvLib*)b; + int cmp = strcmp(lilv_node_as_uri(lib_a->uri), + lilv_node_as_uri(lib_b->uri)); + return cmp ? cmp : strcmp(lib_a->bundle_path, lib_b->bundle_path); +} + /** Get an element of a collection of any object with an LilvHeader by URI. */ struct LilvHeader* lilv_collection_get_by_uri(const ZixTree* const_seq, |