From 8eb2505498ba0e51f0d861a92a365e1766d43b76 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Thu, 20 Sep 2007 16:21:35 +0000
Subject: Add locking support to RDF stuff for dealing with concurrent librdf
 use.

git-svn-id: http://svn.drobilla.net/lad/raul@739 a436a847-0d15-0410-975c-d299462d15a1
---
 src/RDFModel.cpp | 19 +++++++++++++++++++
 src/RDFNode.cpp  | 30 ++++++++++++++++++++++--------
 src/RDFQuery.cpp |  4 +++-
 src/RDFWorld.cpp |  1 +
 4 files changed, 45 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/RDFModel.cpp b/src/RDFModel.cpp
index 0e16036..33629ba 100644
--- a/src/RDFModel.cpp
+++ b/src/RDFModel.cpp
@@ -39,6 +39,7 @@ Model::Model(RDF::World& world)
 	: _world(world)
 	, _serializer(NULL)
 { 
+	Glib::Mutex::Lock lock(world.mutex());
 	_storage = librdf_new_storage(_world.world(), "hashes", NULL, "hash-type='memory'");
 	_model = librdf_new_model(_world.world(), _storage, NULL);
 }
@@ -50,6 +51,7 @@ Model::Model(World& world, const Glib::ustring& data_uri, Glib::ustring base_uri
 	: _world(world)
 	, _serializer(NULL)
 {
+	Glib::Mutex::Lock lock(world.mutex());
 	_storage = librdf_new_storage(_world.world(), "hashes", NULL, "hash-type='memory'");
 	_model = librdf_new_model(_world.world(), _storage, NULL);
 
@@ -82,6 +84,8 @@ Model::Model(World& world, const Glib::ustring& data_uri, Glib::ustring base_uri
 
 Model::~Model()
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	if (_serializer)
 		librdf_free_serializer(_serializer);
 
@@ -93,6 +97,7 @@ Model::~Model()
 void
 Model::setup_prefixes()
 {
+	Glib::Mutex::Lock lock(_world.mutex());
 	assert(_serializer);
 
 	for (Namespaces::const_iterator i = _world.prefixes().begin(); i != _world.prefixes().end(); ++i) {
@@ -109,6 +114,8 @@ Model::setup_prefixes()
 void
 Model::serialize_to_file_handle(FILE* fd)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	_serializer = librdf_new_serializer(_world.world(), RDF_LANG, NULL, NULL);
 	setup_prefixes();
 	librdf_serializer_serialize_model_to_file_handle(_serializer, fd, NULL, _model);
@@ -126,6 +133,8 @@ Model::serialize_to_file_handle(FILE* fd)
 void
 Model::serialize_to_file(const Glib::ustring& uri_str)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	librdf_uri* uri = librdf_new_uri(_world.world(), (const unsigned char*)uri_str.c_str());
 	if (uri && librdf_uri_is_file_uri(uri)) {
 		_serializer = librdf_new_serializer(_world.world(), RDF_LANG, NULL, NULL);
@@ -148,6 +157,8 @@ Model::serialize_to_file(const Glib::ustring& uri_str)
 string
 Model::serialize_to_string()
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	_serializer = librdf_new_serializer(_world.world(), RDF_LANG, NULL, NULL);
 	setup_prefixes();
 
@@ -169,6 +180,8 @@ Model::add_statement(const Node& subject,
                      const Node& predicate,
                      const Node& object)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	librdf_statement* triple = librdf_new_statement_from_nodes(_world.world(),
 			subject.get_node(), predicate.get_node(), object.get_node());
 	
@@ -181,6 +194,8 @@ Model::add_statement(const Node&   subject,
                      const string& predicate_id,
                      const Node&   object)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	const string predicate_uri = _world.expand_uri(predicate_id);
 	librdf_node* predicate = librdf_new_node_from_uri_string(_world.world(),
 			(const unsigned char*)predicate_uri.c_str());
@@ -197,6 +212,8 @@ Model::add_statement(const Node& subject,
                      const Node& predicate,
                      const Atom& object)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	librdf_node* atom_node = AtomRedland::atom_to_rdf_node(_world.world(), object);
 
 	if (atom_node) {
@@ -214,6 +231,8 @@ Model::add_statement(const Node&   subject,
                      const string& predicate_id,
                      const Atom&   object)
 {
+	Glib::Mutex::Lock lock(_world.mutex());
+
 	const string predicate_uri = _world.expand_uri(predicate_id);
 	librdf_node* predicate = librdf_new_node_from_uri_string(_world.world(),
 			(const unsigned char*)predicate_uri.c_str());
diff --git a/src/RDFNode.cpp b/src/RDFNode.cpp
index be529e7..01c0ffb 100644
--- a/src/RDFNode.cpp
+++ b/src/RDFNode.cpp
@@ -27,7 +27,10 @@ namespace RDF {
 
 
 Node::Node(World& world, Type type, const std::string& s)
+	: _world(&world)
 {
+	Glib::Mutex::Lock lock(world.mutex(), Glib::TRY_LOCK);
+
 	if (type == RESOURCE) {
 		const string uri = world.expand_uri(s);
 		_node = librdf_new_node_from_uri_string(world.world(), (const unsigned char*)uri.c_str());
@@ -37,35 +40,46 @@ Node::Node(World& world, Type type, const std::string& s)
 		_node = librdf_new_node_from_blank_identifier(world.world(), (const unsigned char*)s.c_str());
 	} else {
 		_node = NULL;
-		}
+	}
 
 	assert(this->type() == type);
 }
 	
 
 Node::Node(World& world)
-	: _node(librdf_new_node(world.world()))
+	: _world(&world)
 {
+	Glib::Mutex::Lock lock(world.mutex(), Glib::TRY_LOCK);
+	_node = librdf_new_node(world.world());
 }
 
 
-Node::Node(librdf_node* node)
-	: _node(librdf_new_node_from_node(node))
+Node::Node(World& world, librdf_node* node)
+	: _world(&world)
 {
-	assert(node);
+	Glib::Mutex::Lock lock(world.mutex(), Glib::TRY_LOCK);
+	_node = librdf_new_node_from_node(node);
 }
 
 
 Node::Node(const Node& other)
-	: _node(other._node ? librdf_new_node_from_node(other._node): NULL)
+	: _world(other.world())
+	, _node(NULL)
 {
+	if (_world) {
+		Glib::Mutex::Lock lock(_world->mutex(), Glib::TRY_LOCK);
+		_node = (other._node ? librdf_new_node_from_node(other._node) : NULL);
+	}
 }
 
 
 Node::~Node()
 {
-	if (_node)
-		librdf_free_node(_node);
+	if (_world) {
+		Glib::Mutex::Lock lock(_world->mutex(), Glib::TRY_LOCK);
+		if (_node)
+			librdf_free_node(_node);
+	}
 }
 
 
diff --git a/src/RDFQuery.cpp b/src/RDFQuery.cpp
index dc41f56..41aa918 100644
--- a/src/RDFQuery.cpp
+++ b/src/RDFQuery.cpp
@@ -30,6 +30,8 @@ namespace RDF {
 Query::Results
 Query::run(World& world, Model& model, const Glib::ustring base_uri_str) const
 {
+	Glib::Mutex::Lock lock(world.mutex());
+
 	//cout << "\n**************** QUERY *******************\n";
 	//cout << _query << endl;
 	//cout << "******************************************\n\n";
@@ -65,7 +67,7 @@ Query::run(World& world, Model& model, const Glib::ustring base_uri_str) const
 			librdf_node* value = librdf_query_results_get_binding_value(results, i);
 
 			if (name && value)
-				bindings.insert(std::make_pair(std::string(name), Node(value)));
+				bindings.insert(std::make_pair(std::string(name), Node(world, value)));
 		}
 
 		result.push_back(bindings);
diff --git a/src/RDFWorld.cpp b/src/RDFWorld.cpp
index 17805ba..d68919d 100644
--- a/src/RDFWorld.cpp
+++ b/src/RDFWorld.cpp
@@ -46,6 +46,7 @@ World::World()
 
 World::~World()
 {
+	Glib::Mutex::Lock lock(_mutex);
 	librdf_free_world(_world);
 }
 
-- 
cgit v1.2.1