summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-11-22 08:00:59 +0000
committerDavid Robillard <d@drobilla.net>2008-11-22 08:00:59 +0000
commitcda796269b903899edcbc479dbdc3c7dacb944c5 (patch)
treeb64164e3d916127f5adefd6b8bb6379bd5ea41a8
parentfc397802d408441ce354c5b0328adc93f617aca5 (diff)
downloadingen-cda796269b903899edcbc479dbdc3c7dacb944c5.tar.gz
ingen-cda796269b903899edcbc479dbdc3c7dacb944c5.tar.bz2
ingen-cda796269b903899edcbc479dbdc3c7dacb944c5.zip
Finer grained locking on RDF world lock when parsing: prevents deadlock on loading massive patches that fill the event queue.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1765 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/QueuedEventSource.cpp10
-rw-r--r--src/gui/PatchCanvas.cpp12
-rw-r--r--src/serialisation/Parser.cpp45
3 files changed, 47 insertions, 20 deletions
diff --git a/src/engine/QueuedEventSource.cpp b/src/engine/QueuedEventSource.cpp
index 69ab805a..e9817c4b 100644
--- a/src/engine/QueuedEventSource.cpp
+++ b/src/engine/QueuedEventSource.cpp
@@ -114,13 +114,9 @@ QueuedEventSource::process(PostProcessor& dest, ProcessContext& context)
++num_events_processed;
}
- if (_full_semaphore.has_waiter() && num_events_processed > 0)
- _full_semaphore.post();
-
- /*if (num_events_processed > 0)
- dest.whip();*/
- //else
- // cerr << "NO PROC: queued: " << unprepared_events() << ", stamped: " << !_stamped_queue.empty() << endl;
+ if (num_events_processed > 0)
+ while (_full_semaphore.has_waiter())
+ _full_semaphore.post();
}
diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp
index 0d444ad3..c2cef4c8 100644
--- a/src/gui/PatchCanvas.cpp
+++ b/src/gui/PatchCanvas.cpp
@@ -646,7 +646,7 @@ PatchCanvas::paste()
parser->parse_string(App::instance().world(), &avoider, str, "/", _patch->path());
for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) {
- cout << "************ OBJECT: " << i->first << endl;
+ //cout << "************ OBJECT: " << i->first << endl;
if (_patch->path() == "/" && i->first == "/") {
//cout << "SKIPPING ROOT " << _patch->path() << " :: " << i->first << endl;
continue;
@@ -670,11 +670,17 @@ PatchCanvas::paste()
builder.build(_patch->path(), i->second);
}
- //avoider.set_target(*App::instance().engine());
+ // Successful connections
+ SharedPtr<PatchModel> root = PtrCast<PatchModel>(clipboard.object("/"));
+ assert(root);
+ for (Patch::Connections::const_iterator i = root->connections().begin();
+ i != root->connections().end(); ++i) {
+ App::instance().engine()->connect((*i)->src_port_path(), (*i)->dst_port_path());
+ }
+ // Orphan connections (just in case...)
for (ClientStore::ConnectionRecords::const_iterator i = clipboard.connection_records().begin();
i != clipboard.connection_records().end(); ++i) {
- cout << "CONNECTING " << i->first << " -> " << i->second << endl;
App::instance().engine()->connect(i->first, i->second);
}
}
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index c722b21e..4e2035f1 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -143,15 +143,18 @@ Parser::parse_update(
"}");
results = Redland::Query::Results(query.run(*world->rdf_world, model, base_uri));
- world->rdf_world->mutex().lock();
+
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string obj_path = (*i)["path"].to_string();
const string key = world->rdf_world->prefixes().qualify((*i)["varkey"].to_string());
const Redland::Node& val_node = (*i)["varval"];
+ const Atom a(AtomRDF::node_to_atom(val_node));
+ world->rdf_world->mutex().unlock();
if (key != "")
- target->set_variable(obj_path, key, AtomRDF::node_to_atom(val_node));
+ target->set_variable(obj_path, key, a);
}
- world->rdf_world->mutex().unlock();
+
// Connections
parse_connections(world, target, model, base_uri, "", "/");
@@ -163,13 +166,15 @@ Parser::parse_update(
"}");
results = Redland::Query::Results(query.run(*world->rdf_world, model, base_uri));
- world->rdf_world->mutex().lock();
+
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string obj_path = (*i)["path"].to_string();
const Redland::Node& val_node = (*i)["value"];
- target->set_port_value(obj_path, AtomRDF::node_to_atom(val_node));
+ const Atom a(AtomRDF::node_to_atom(val_node));
+ world->rdf_world->mutex().unlock();
+ target->set_port_value(obj_path, a);
}
- world->rdf_world->mutex().unlock();
return parse(world, target, model, base_uri, engine_base, object_uri, symbol, data);
}
@@ -365,8 +370,9 @@ Parser::parse_patch(
"}");
Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri);
- world->rdf_world->mutex().lock();
+
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string node_name = (*i)["name"].to_string();
const Path node_path = patch_path.base() + node_name;
@@ -377,19 +383,25 @@ Parser::parse_patch(
const Redland::Node& poly_node = (*i)["poly"];
if (poly_node.is_bool() && poly_node.to_bool() == true)
node_polyphonic = true;
+
+ world->rdf_world->mutex().unlock();
target->new_node(node_path, node_plugin);
target->set_property(node_path, "ingen:polyphonic", node_polyphonic);
created.insert(node_path);
+
+ world->rdf_world->mutex().lock();
}
const string key = world->rdf_world->prefixes().qualify((*i)["varkey"].to_string());
const Redland::Node& val_node = (*i)["varval"];
+
+ world->rdf_world->mutex().unlock();
if (key != "")
target->set_variable(node_path, key, AtomRDF::node_to_atom(val_node));
}
- world->rdf_world->mutex().unlock();
+
/* Load subpatches */
@@ -402,8 +414,10 @@ Parser::parse_patch(
results = query.run(*world->rdf_world, model, base_uri);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string symbol = (*i)["symbol"].to_string();
const string subpatch = (*i)["subpatch"].to_string();
+ world->rdf_world->mutex().unlock();
const Path subpatch_path = patch_path.base() + symbol;
@@ -432,8 +446,10 @@ Parser::parse_patch(
results = query.run(*world->rdf_world, model, base_uri);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string node_name = (*i)["nodename"].to_string();
const string port_name = (*i)["portname"].to_string();
+ world->rdf_world->mutex().unlock();
assert(Path::is_valid_name(node_name));
assert(Path::is_valid_name(port_name));
@@ -460,11 +476,13 @@ Parser::parse_patch(
"}");
results = query.run(*world->rdf_world, model, base_uri);
- world->rdf_world->mutex().lock();
+
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const string name = (*i)["name"].to_string();
const string type = world->rdf_world->qualify((*i)["type"].to_string());
const string datatype = world->rdf_world->qualify((*i)["datatype"].to_string());
+ world->rdf_world->mutex().unlock();
assert(Path::is_valid_name(name));
const Path port_path = patch_path.base() + name;
@@ -476,16 +494,21 @@ Parser::parse_patch(
created.insert(port_path);
}
+ world->rdf_world->mutex().lock();
const Redland::Node& val_node = (*i)["portval"];
+ world->rdf_world->mutex().unlock();
+
target->set_port_value(patch_path.base() + name, AtomRDF::node_to_atom(val_node));
+ world->rdf_world->mutex().lock();
const string key = world->rdf_world->prefixes().qualify((*i)["varkey"].to_string());
const Redland::Node& var_val_node = (*i)["varval"];
+ world->rdf_world->mutex().unlock();
if (key != "")
target->set_variable(patch_path.base() + name, key, AtomRDF::node_to_atom(var_val_node));
}
- world->rdf_world->mutex().unlock();
+
created.clear();
@@ -498,7 +521,9 @@ Parser::parse_patch(
results = query.run(*world->rdf_world, model, base_uri);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ world->rdf_world->mutex().lock();
const Redland::Node& enabled_node = (*i)["enabled"];
+ world->rdf_world->mutex().unlock();
if (enabled_node.is_bool() && enabled_node) {
target->set_property(patch_path, "ingen:enabled", (bool)true);
break;