diff options
author | David Robillard <d@drobilla.net> | 2014-01-18 04:45:30 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2014-01-18 04:45:30 +0000 |
commit | bc64c953d7504c0c3986f2bea9a739cd99f0dd15 (patch) | |
tree | 4bbb3fd75fb3926179c273d04292bb64c43d0eb1 /src/server/events | |
parent | c781c7a5cd0c124b61f38a45ab4564fce022a89b (diff) | |
download | ingen-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/server/events')
-rw-r--r-- | src/server/events/Delta.cpp | 13 | ||||
-rw-r--r-- | src/server/events/Delta.hpp | 2 |
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 |