diff options
author | David Robillard <d@drobilla.net> | 2015-05-23 03:20:40 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2015-05-23 03:20:40 +0000 |
commit | dc5c579778d8b7b6f113c48d202f89c172abd591 (patch) | |
tree | 7a3a24f7acfab09c652ca466a46099766c8a02d3 /src | |
parent | 63d4ffa098e016a9680b4b1b1f209ab3bb3dbd8c (diff) | |
download | ingen-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
Diffstat (limited to 'src')
-rw-r--r-- | src/SocketReader.cpp | 31 | ||||
-rw-r--r-- | src/World.cpp | 3 | ||||
-rw-r--r-- | src/gui/GraphCanvas.cpp | 4 | ||||
-rw-r--r-- | src/gui/ThreadedLoader.cpp | 25 | ||||
-rw-r--r-- | src/gui/ThreadedLoader.hpp | 5 | ||||
-rw-r--r-- | src/ingen/ingen.cpp | 2 | ||||
-rw-r--r-- | src/server/JackDriver.cpp | 2 | ||||
-rw-r--r-- | src/server/ingen_lv2.cpp | 14 |
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); |