summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-05-23 03:20:40 +0000
committerDavid Robillard <d@drobilla.net>2015-05-23 03:20:40 +0000
commitdc5c579778d8b7b6f113c48d202f89c172abd591 (patch)
tree7a3a24f7acfab09c652ca466a46099766c8a02d3
parent63d4ffa098e016a9680b4b1b1f209ab3bb3dbd8c (diff)
downloadingen-dc5c579778d8b7b6f113c48d202f89c172abd591.tar.gz
ingen-dc5c579778d8b7b6f113c48d202f89c172abd591.tar.bz2
ingen-dc5c579778d8b7b6f113c48d202f89c172abd591.zip
Prevent concurrent Sord access.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5683 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/SocketReader.cpp31
-rw-r--r--src/World.cpp3
-rw-r--r--src/gui/GraphCanvas.cpp4
-rw-r--r--src/gui/ThreadedLoader.cpp25
-rw-r--r--src/gui/ThreadedLoader.hpp5
-rw-r--r--src/ingen/ingen.cpp2
-rw-r--r--src/server/JackDriver.cpp2
-rw-r--r--src/server/ingen_lv2.cpp14
8 files changed, 69 insertions, 17 deletions
diff --git a/src/SocketReader.cpp b/src/SocketReader.cpp
index 125d904f..85f55f08 100644
--- a/src/SocketReader.cpp
+++ b/src/SocketReader.cpp
@@ -99,10 +99,6 @@ SocketReader::run()
return;
}
- // Use <ingen:/root/> as base URI so e.g. </foo/bar> will be a path
- SordNode* base_uri = sord_new_uri(
- world->c_obj(), (const uint8_t*)"ingen:/root/");
-
// Set up sratom and a forge to build LV2 atoms from model
Sratom* sratom = sratom_new(map);
SerdChunk chunk = { NULL, 0 };
@@ -111,11 +107,23 @@ SocketReader::run()
lv2_atom_forge_set_sink(
&forge, sratom_forge_sink, sratom_forge_deref, &chunk);
- // Make a model and reader to parse the next Turtle message
- _env = world->prefixes().c_obj();
- SordModel* model = sord_new(world->c_obj(), SORD_SPO, false);
+ SordNode* base_uri = NULL;
+ SordModel* model = NULL;
+ {
+ // Lock RDF world
+ std::lock_guard<std::mutex> lock(_world.rdf_mutex());
+
+ // Use <ingen:/root/> as base URI so e.g. </foo/bar> will be a path
+ base_uri = sord_new_uri(
+ world->c_obj(), (const uint8_t*)"ingen:/root/");
+
+ // Make a model and reader to parse the next Turtle message
+ _env = world->prefixes().c_obj();
+ model = sord_new(world->c_obj(), SORD_SPO, false);
- _inserter = sord_inserter_new(model, _env);
+ // Create an inserter for writing incoming triples to model
+ _inserter = sord_inserter_new(model, _env);
+ }
SerdReader* reader = serd_reader_new(
SERD_TURTLE, this, NULL,
@@ -152,6 +160,9 @@ SocketReader::run()
continue; // No data, shouldn't happen
}
+ // Lock RDF world
+ std::lock_guard<std::mutex> lock(_world.rdf_mutex());
+
// Read until the next '.'
SerdStatus st = serd_reader_read_chunk(reader);
if (st == SERD_FAILURE || !_msg_node) {
@@ -174,6 +185,10 @@ SocketReader::run()
_msg_node = NULL;
}
+ // Lock RDF world
+ std::lock_guard<std::mutex> lock(_world.rdf_mutex());
+
+ // Destroy everything
fclose(f);
sord_inserter_free(_inserter);
serd_reader_end_stream(reader);
diff --git a/src/World.cpp b/src/World.cpp
index 4ebcaf8a..6686a9bf 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -217,6 +217,7 @@ public:
SPtr<Parser> parser;
SPtr<Store> store;
LilvWorld* lilv_world;
+ std::mutex rdf_mutex;
std::string jack_uuid;
};
@@ -251,6 +252,8 @@ char**& World::argv() { return _impl->argv; }
Configuration& World::conf() { return _impl->conf; }
Log& World::log() { return _impl->log; }
+std::mutex& World::rdf_mutex() { return _impl->rdf_mutex; }
+
Sord::World* World::rdf_world() { return _impl->rdf_world; }
LilvWorld* World::lilv_world() { return _impl->lilv_world; }
diff --git a/src/gui/GraphCanvas.cpp b/src/gui/GraphCanvas.cpp
index ddbebfe7..0725aa67 100644
--- a/src/gui/GraphCanvas.cpp
+++ b/src/gui/GraphCanvas.cpp
@@ -598,6 +598,8 @@ serialise_arc(GanvEdge* arc, void* data)
void
GraphCanvas::copy_selection()
{
+ std::lock_guard<std::mutex> lock(_app.world()->rdf_mutex());
+
Serialiser serialiser(*_app.world());
serialiser.start_to_string(_graph->path(), _graph->base_uri());
@@ -614,6 +616,8 @@ GraphCanvas::paste()
{
typedef Node::Properties::const_iterator PropIter;
+ std::lock_guard<std::mutex> lock(_app.world()->rdf_mutex());
+
const Glib::ustring str = Gtk::Clipboard::get()->wait_for_text();
SPtr<Parser> parser = _app.loader()->parser();
const URIs& uris = _app.uris();
diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp
index 8b7797cb..98314b66 100644
--- a/src/gui/ThreadedLoader.cpp
+++ b/src/gui/ThreadedLoader.cpp
@@ -77,8 +77,6 @@ ThreadedLoader::load_graph(bool merge,
{
_mutex.lock();
- Ingen::World* world = _app.world();
-
Glib::ustring engine_base = "";
if (engine_parent) {
if (merge)
@@ -89,10 +87,7 @@ ThreadedLoader::load_graph(bool merge,
_events.push_back(
sigc::hide_return(
- sigc::bind(sigc::mem_fun(world->parser().get(),
- &Ingen::Parser::parse_file),
- _app.world(),
- _app.world()->interface().get(),
+ sigc::bind(sigc::mem_fun(this, &ThreadedLoader::load_graph_event),
document_uri,
engine_parent,
engine_symbol,
@@ -103,6 +98,22 @@ ThreadedLoader::load_graph(bool merge,
}
void
+ThreadedLoader::load_graph_event(const Glib::ustring& document_uri,
+ optional<Raul::Path> engine_parent,
+ optional<Raul::Symbol> engine_symbol,
+ optional<Node::Properties> engine_data)
+{
+ std::lock_guard<std::mutex> lock(_app.world()->rdf_mutex());
+
+ _app.world()->parser()->parse_file(_app.world(),
+ _app.world()->interface().get(),
+ document_uri,
+ engine_parent,
+ engine_symbol,
+ engine_data);
+}
+
+void
ThreadedLoader::save_graph(SPtr<const Client::GraphModel> model,
const string& filename)
{
@@ -122,6 +133,8 @@ ThreadedLoader::save_graph_event(SPtr<const Client::GraphModel> model,
const string& filename)
{
if (_app.serialiser()) {
+ std::lock_guard<std::mutex> lock(_app.world()->rdf_mutex());
+
if (filename.find(".ingen") != string::npos) {
_app.serialiser()->write_bundle(model, filename);
} else {
diff --git a/src/gui/ThreadedLoader.hpp b/src/gui/ThreadedLoader.hpp
index 87f1971b..7870761a 100644
--- a/src/gui/ThreadedLoader.hpp
+++ b/src/gui/ThreadedLoader.hpp
@@ -65,6 +65,11 @@ public:
SPtr<Parser> parser();
private:
+ void load_graph_event(const Glib::ustring& document_uri,
+ boost::optional<Raul::Path> engine_parent,
+ boost::optional<Raul::Symbol> engine_symbol,
+ boost::optional<Node::Properties> engine_data);
+
void save_graph_event(SPtr<const Client::GraphModel> model,
const std::string& filename);
diff --git a/src/ingen/ingen.cpp b/src/ingen/ingen.cpp
index 12a17e99..357f42b5 100644
--- a/src/ingen/ingen.cpp
+++ b/src/ingen/ingen.cpp
@@ -177,6 +177,8 @@ main(int argc, char** argv)
engine_interface->get(Raul::URI("ingen:/plugins"));
engine_interface->get(Node::root_uri());
+
+ std::lock_guard<std::mutex> lock(world->rdf_mutex());
world->parser()->parse_file(
world, engine_interface.get(), graph, parent, symbol);
}
diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp
index ab4054b7..b4e3add3 100644
--- a/src/server/JackDriver.cpp
+++ b/src/server/JackDriver.cpp
@@ -527,6 +527,8 @@ JackDriver::_session_cb(jack_session_event_t* event)
SPtr<Serialiser> serialiser = _engine.world()->serialiser();
if (serialiser) {
+ std::lock_guard<std::mutex> lock(_engine.world()->rdf_mutex());
+
SPtr<Node> root(_engine.root_graph(), NullDeleter<Node>);
serialiser->write_bundle(root, string("file://") + event->session_dir);
}
diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp
index 2259b758..8265cce8 100644
--- a/src/server/ingen_lv2.cpp
+++ b/src/server/ingen_lv2.cpp
@@ -583,6 +583,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
engine->process_events();
engine->post_processor()->process();
+ std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
+
plugin->world->parser()->parse_file(plugin->world,
plugin->world->interface().get(),
graph->filename);
@@ -707,9 +709,14 @@ ingen_save(LV2_Handle instance,
char* state_path = map_path->abstract_path(map_path->handle, real_path);
Ingen::Store::iterator root = plugin->world->store()->find(Raul::Path("/"));
- plugin->world->serialiser()->start_to_file(root->second->path(), real_path);
- plugin->world->serialiser()->serialise(root->second);
- plugin->world->serialiser()->finish();
+
+ {
+ std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
+
+ plugin->world->serialiser()->start_to_file(root->second->path(), real_path);
+ plugin->world->serialiser()->serialise(root->second);
+ plugin->world->serialiser()->finish();
+ }
store(handle,
ingen_file,
@@ -772,6 +779,7 @@ ingen_restore(LV2_Handle instance,
}
// Load new graph
+ std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
plugin->world->parser()->parse_file(
plugin->world, plugin->world->interface().get(), real_path);