diff options
-rw-r--r-- | slv2/world.h | 25 | ||||
-rw-r--r-- | src/slv2_internal.h | 12 | ||||
-rw-r--r-- | src/world.c | 63 |
3 files changed, 99 insertions, 1 deletions
diff --git a/slv2/world.h b/slv2/world.h index e4e135d..a133010 100644 --- a/slv2/world.h +++ b/slv2/world.h @@ -70,6 +70,31 @@ slv2_world_new_using_rdf_world(librdf_world* world); void slv2_world_free(SLV2World world); +#if 0 +/** Set the RDF lock function. + * + * If set, this function will be called before any calls to librdf functions. + * This can be used to make SLV2 thread-safe. + * + * \a lock will be called with \a data as a parameter, whenever SLV2 is going + * to perform an RDF operation. + */ +void +slv2_world_set_rdf_lock_function(SLV2World world, void (*lock)(void*), void* data); + + +/** Set the unlock function. + * + * This is the counterpart to the RDF lock function set with + * slv2_world_set_rdf_lock_function. Be sure to call this after locking, + * or a deadlock will occur. + * + * \a unlock will be called with the same data pointer set with + * slv2_world_set_rdf_lock_function. + */ +void +slv2_world_set_rdf_unlock_function(SLV2World world, void (*unlock)(void*)); +#endif /** Load all installed LV2 bundles on the system. * diff --git a/src/slv2_internal.h b/src/slv2_internal.h index 2694b5d..4e8c8da 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -133,7 +133,6 @@ void slv2_plugin_classes_free(); /* ********* World ********* */ - /** Model of LV2 (RDF) data loaded from bundles. */ struct _SLV2World { @@ -145,8 +144,19 @@ struct _SLV2World { SLV2Plugins plugins; librdf_node* lv2_plugin_node; librdf_node* rdf_a_node; + + void (*rdf_lock)(void*); + void (*rdf_unlock)(void*); + void* rdf_lock_data; + int rdf_lock_count; }; +void +slv2_world_lock_if_necessary(SLV2World world); + +void +slv2_world_unlock_if_necessary(SLV2World world); + /** Load all bundles found in \a search_path. * * \param search_path A colon-delimited list of directories. These directories diff --git a/src/world.c b/src/world.c index 898ab5a..d3776e5 100644 --- a/src/world.c +++ b/src/world.c @@ -67,6 +67,11 @@ slv2_world_new() world->rdf_a_node = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + + world->rdf_lock = NULL; + world->rdf_unlock = NULL; + world->rdf_lock_data = NULL; + world->rdf_lock_count = 0; return world; @@ -110,6 +115,11 @@ slv2_world_new_using_rdf_world(librdf_world* rdf_world) world->rdf_a_node = librdf_new_node_from_uri_string(rdf_world, (unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + + world->rdf_lock = NULL; + world->rdf_unlock = NULL; + world->rdf_lock_data = NULL; + world->rdf_lock_count = 0; return world; @@ -122,6 +132,9 @@ fail: void slv2_world_free(SLV2World world) { + if (world->rdf_lock) + world->rdf_lock(world->rdf_lock_data); + librdf_free_node(world->lv2_plugin_node); librdf_free_node(world->rdf_a_node); @@ -144,14 +157,62 @@ slv2_world_free(SLV2World world) librdf_free_world(world->world); world->world = NULL; + + if (world->rdf_unlock) + world->rdf_unlock(world->rdf_lock_data); free(world); } void +slv2_world_set_rdf_lock_function(SLV2World world, void (*lock)(void*), void* data) +{ + world->rdf_lock = lock; + world->rdf_lock_data = data; +} + + +void +slv2_world_set_rdf_unlock_function(SLV2World world, void (*unlock)(void*)) +{ + world->rdf_unlock = unlock; +} + + +void +slv2_world_lock_if_necessary(SLV2World world) +{ + if (world->rdf_lock) { + + if (world->rdf_lock_count == 0) + world->rdf_lock(world->rdf_lock_data); + + ++world->rdf_lock_count; + + } +} + + +void +slv2_world_unlock_if_necessary(SLV2World world) +{ + if (world->rdf_lock && world->rdf_lock_count > 0) { + + if (world->rdf_lock_count == 1 && world->rdf_unlock) + world->rdf_unlock(world->rdf_lock_data); + + world->rdf_lock_count = 0; + + } +} + + +void slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) { + slv2_world_lock_if_necessary(world); + librdf_uri* bundle_uri = librdf_new_uri(world->world, (const unsigned char*)bundle_uri_str); @@ -209,6 +270,8 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) librdf_free_storage(manifest_storage); librdf_free_uri(manifest_uri); librdf_free_uri(bundle_uri); + + slv2_world_unlock_if_necessary(world); } |