summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-01-18 04:45:30 +0000
committerDavid Robillard <d@drobilla.net>2014-01-18 04:45:30 +0000
commitbc64c953d7504c0c3986f2bea9a739cd99f0dd15 (patch)
tree4bbb3fd75fb3926179c273d04292bb64c43d0eb1 /src
parentc781c7a5cd0c124b61f38a45ab4564fce022a89b (diff)
downloadingen-bc64c953d7504c0c3986f2bea9a739cd99f0dd15.tar.gz
ingen-bc64c953d7504c0c3986f2bea9a739cd99f0dd15.tar.bz2
ingen-bc64c953d7504c0c3986f2bea9a739cd99f0dd15.zip
Fix crashes when LV2 host changes polyphony rapidly.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5315 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/server/events/Delta.cpp13
-rw-r--r--src/server/events/Delta.hpp2
2 files changed, 15 insertions, 0 deletions
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 2e6ab18c..d551335f 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -63,6 +63,7 @@ Delta::Delta(Engine& engine,
, _compiled_graph(NULL)
, _context(context)
, _create(create)
+ , _poly_lock(engine.store()->lock(), Glib::NOT_LOCK)
{
if (context != Resource::Graph::DEFAULT) {
for (auto& p : _properties) {
@@ -103,6 +104,7 @@ Delta::pre_process()
{
const bool is_graph_object = Node::uri_is_path(_subject);
const bool is_client = (_subject == "ingen:/clients/this");
+ bool poly_changed = false;
// Take a writer lock while we modify the store
Glib::RWLock::WriterLock lock(_engine.store()->lock());
@@ -217,6 +219,7 @@ Delta::pre_process()
if (value.get<int32_t>() < 1 || value.get<int32_t>() > 128) {
_status = Status::INVALID_POLY;
} else {
+ poly_changed = true;
op = SpecialType::POLYPHONY;
_graph->prepare_internal_poly(
*_engine.buffer_factory(), value.get<int32_t>());
@@ -231,6 +234,7 @@ Delta::pre_process()
GraphImpl* parent = dynamic_cast<GraphImpl*>(obj->parent());
if (parent) {
if (value.type() == uris.forge.Bool) {
+ poly_changed = true;
op = SpecialType::POLYPHONIC;
obj->set_property(key, value, value.context());
BlockImpl* block = dynamic_cast<BlockImpl*>(obj);
@@ -260,6 +264,11 @@ Delta::pre_process()
_types.push_back(op);
}
+ if (poly_changed) {
+ lock.release();
+ _poly_lock.acquire();
+ }
+
return Event::pre_process_done(
_status == Status::NOT_PREPARED ? Status::SUCCESS : _status,
_subject);
@@ -350,6 +359,10 @@ Delta::execute(ProcessContext& context)
void
Delta::post_process()
{
+ if (_poly_lock.locked()) {
+ _poly_lock.release();
+ }
+
Broadcaster::Transfer t(*_engine.broadcaster());
for (auto& s : _set_events)
diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp
index 7e3f5257..451b8e62 100644
--- a/src/server/events/Delta.hpp
+++ b/src/server/events/Delta.hpp
@@ -112,6 +112,8 @@ private:
bool _create;
SPtr<ControlBindings::Bindings> _old_bindings;
+
+ Glib::RWLock::WriterLock _poly_lock; ///< Long-term lock for poly changes
};
} // namespace Events