summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-07-25 05:01:28 +0000
committerDavid Robillard <d@drobilla.net>2007-07-25 05:01:28 +0000
commit9f43f23510ba2acd8e03f2822d87c74a8774b9d6 (patch)
treefc29ca27803d92e78f3cfdf9838896351c21c052
parent092c9d03af043af4bad2d2402ee9c75d68dca67a (diff)
downloadlilv-9f43f23510ba2acd8e03f2822d87c74a8774b9d6.tar.gz
lilv-9f43f23510ba2acd8e03f2822d87c74a8774b9d6.tar.bz2
lilv-9f43f23510ba2acd8e03f2822d87c74a8774b9d6.zip
Start work on lock stuff, for threadsafe SLV2 and using SLV2 with apps that use Redland themselves.
git-svn-id: http://svn.drobilla.net/lad/slv2@621 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--slv2/world.h25
-rw-r--r--src/slv2_internal.h12
-rw-r--r--src/world.c63
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);
}