From 02ae3e9d8bf3f6a5e844706721aad8c0ac9f4340 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 18 Jan 2017 15:28:04 -0500 Subject: Fix invalid cross-thread use of mutex Instead of abusing store mutex for this purpose, extend blocking mechanism of the PreProcessor (designed for atomic bundle execution) to support execution of individual atomic events which must be executed before the next event can be pre-processed. --- src/server/events/Delta.cpp | 29 ++++++++++++----------------- src/server/events/Delta.hpp | 4 +++- 2 files changed, 15 insertions(+), 18 deletions(-) (limited to 'src/server/events') diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index c623d51e..3ee17ee2 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -65,7 +65,7 @@ Delta::Delta(Engine& engine, , _state(NULL) , _context(context) , _type(type) - , _poly_lock(engine.store()->mutex(), std::defer_lock) + , _block(false) { if (context != Resource::Graph::DEFAULT) { for (auto& p : _properties) { @@ -136,7 +136,6 @@ Delta::pre_process(PreProcessContext& ctx) const bool is_client = (_subject == "ingen:/clients/this"); const bool is_engine = (_subject == "ingen:/"); const bool is_file = (_subject.substr(0, 5) == "file:"); - bool poly_changed = false; if (_type == Type::PUT && is_file) { // Ensure type is Preset, the only supported file put @@ -175,8 +174,7 @@ Delta::pre_process(PreProcessContext& ctx) } } - // Take a writer lock while we modify the store - std::unique_lock lock(_engine.store()->mutex()); + std::lock_guard lock(_engine.store()->mutex()); _object = is_graph_object ? static_cast(_engine.store()->get(Node::uri_to_path(_subject))) @@ -362,8 +360,8 @@ Delta::pre_process(PreProcessContext& ctx) if (value.get() < 1 || value.get() > 128) { _status = Status::INVALID_POLY; } else { - poly_changed = true; - op = SpecialType::POLYPHONY; + _block = true; + op = SpecialType::POLYPHONY; _graph->prepare_internal_poly( *_engine.buffer_factory(), value.get()); } @@ -380,8 +378,8 @@ Delta::pre_process(PreProcessContext& ctx) } else if (value.type() != uris.forge.Bool) { _status = Status::BAD_VALUE_TYPE; } else { - poly_changed = true; - op = SpecialType::POLYPHONIC; + _block = true; + op = SpecialType::POLYPHONIC; obj->set_property(key, value, value.context()); BlockImpl* block = dynamic_cast(obj); if (block) { @@ -427,11 +425,6 @@ Delta::pre_process(PreProcessContext& ctx) s->pre_process(ctx); } - if (poly_changed) { - lock.unlock(); - _poly_lock.lock(); - } - return Event::pre_process_done( _status == Status::NOT_PREPARED ? Status::SUCCESS : _status, _subject); @@ -536,10 +529,6 @@ Delta::execute(RunContext& context) void Delta::post_process() { - if (_poly_lock.owns_lock()) { - _poly_lock.unlock(); - } - if (_state) { BlockImpl* block = dynamic_cast(_object); if (block) { @@ -620,6 +609,12 @@ Delta::undo(Interface& target) } } +Event::Execution +Delta::get_execution() const +{ + return _block ? Execution::ATOMIC : Execution::NORMAL; +} + } // namespace Events } // namespace Server } // namespace Ingen diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp index ca9d0276..d2326cd9 100644 --- a/src/server/events/Delta.hpp +++ b/src/server/events/Delta.hpp @@ -78,6 +78,8 @@ public: void post_process(); void undo(Interface& target); + Execution get_execution() const; + private: enum class SpecialType { NONE, @@ -115,7 +117,7 @@ private: boost::optional _preset; - std::unique_lock _poly_lock; ///< Long-term lock for poly changes + bool _block; }; } // namespace Events -- cgit v1.2.1