From 74a711e0d1cdb5c505a227dc9b1925657f1e778d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 24 Sep 2011 03:22:30 +0000 Subject: Use store lock to avoid race conditions with Get and create/delete events. Get really shouldn't be reading the store (via ObjectSender) in the post processing thread at all, avoiding that entirely would be a better solution. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3484 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/events/CreateNode.cpp | 9 ++++++++- src/server/events/CreateNode.hpp | 9 +++++++-- src/server/events/CreatePort.cpp | 9 ++++++++- src/server/events/CreatePort.hpp | 11 ++++++++--- src/server/events/Delete.cpp | 4 ++++ src/server/events/Delete.hpp | 2 ++ src/server/events/Get.cpp | 5 +++++ src/server/events/Get.hpp | 11 +++++++---- 8 files changed, 49 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp index 01d4f285..39d5f86d 100644 --- a/src/server/events/CreateNode.cpp +++ b/src/server/events/CreateNode.cpp @@ -57,6 +57,7 @@ CreateNode::CreateNode( , _node_already_exists(false) , _polyphonic(false) , _properties(properties) + , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK) { const Resource::Properties::const_iterator p = properties.find( engine.world()->uris()->ingen_polyphonic); @@ -68,6 +69,8 @@ CreateNode::CreateNode( void CreateNode::pre_process() { + _lock.acquire(); + if (_engine.engine_store()->find_object(_path) != NULL) { _node_already_exists = true; QueuedEvent::pre_process(); @@ -117,8 +120,10 @@ CreateNode::execute(ProcessContext& context) void CreateNode::post_process() { - if (!_request) + if (!_request) { + _lock.release(); return; + } string msg; if (_node_already_exists) { @@ -138,6 +143,8 @@ CreateNode::post_process() _request->respond_ok(); _engine.broadcaster()->send_object(_node, true); // yes, send ports } + + _lock.release(); } } // namespace Server diff --git a/src/server/events/CreateNode.hpp b/src/server/events/CreateNode.hpp index bbaf830b..47f86622 100644 --- a/src/server/events/CreateNode.hpp +++ b/src/server/events/CreateNode.hpp @@ -19,9 +19,13 @@ #define INGEN_EVENTS_CREATENODE_HPP #include -#include "QueuedEvent.hpp" + +#include + #include "ingen/Resource.hpp" +#include "QueuedEvent.hpp" + namespace Ingen { namespace Server { @@ -61,7 +65,8 @@ private: bool _node_already_exists; bool _polyphonic; - Resource::Properties _properties; + Resource::Properties _properties; + Glib::RWLock::WriterLock _lock; }; } // namespace Server diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp index 4541892b..fdf675a6 100644 --- a/src/server/events/CreatePort.cpp +++ b/src/server/events/CreatePort.cpp @@ -58,6 +58,7 @@ CreatePort::CreatePort( , _patch_port(NULL) , _driver_port(NULL) , _properties(properties) + , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK) { /* This is blocking because of the two different sets of Patch ports, the array used in the * audio thread (inherited from NodeImpl), and the arrays used in the pre processor thread. @@ -74,6 +75,8 @@ CreatePort::CreatePort( void CreatePort::pre_process() { + _lock.acquire(); + if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) { QueuedEvent::pre_process(); return; @@ -161,8 +164,10 @@ CreatePort::execute(ProcessContext& context) void CreatePort::post_process() { - if (!_request) + if (!_request) { + _lock.release(); return; + } string msg; switch (_error) { @@ -183,6 +188,8 @@ CreatePort::post_process() _request->respond_error(msg); break; } + + _lock.release(); } } // namespace Server diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp index ae44e2f1..e3c13fa1 100644 --- a/src/server/events/CreatePort.hpp +++ b/src/server/events/CreatePort.hpp @@ -18,12 +18,16 @@ #ifndef INGEN_EVENTS_CREATEPORT_HPP #define INGEN_EVENTS_CREATEPORT_HPP -#include "QueuedEvent.hpp" -#include "raul/Path.hpp" +#include + #include "raul/Array.hpp" +#include "raul/Path.hpp" + #include "ingen/PortType.hpp" #include "ingen/Resource.hpp" +#include "QueuedEvent.hpp" + namespace Ingen { namespace Server { @@ -71,7 +75,8 @@ private: DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port bool _succeeded; - Resource::Properties _properties; + Resource::Properties _properties; + Glib::RWLock::WriterLock _lock; }; } // namespace Server diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index b1dc1558..4f13cd97 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -50,6 +50,7 @@ Delete::Delete(Engine& engine, , _ports_array(NULL) , _compiled_patch(NULL) , _disconnect_event(NULL) + , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK) { assert(request); assert(request->source()); @@ -71,6 +72,8 @@ Delete::pre_process() return; } + _lock.acquire(); + _removed_bindings = _engine.control_bindings()->remove(_path); _store_iterator = _engine.engine_store()->find(_path); @@ -170,6 +173,7 @@ Delete::execute(ProcessContext& context) void Delete::post_process() { + _lock.release(); _removed_bindings.reset(); if (!Raul::Path::is_path(_uri) diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp index ba256d87..d865ca11 100644 --- a/src/server/events/Delete.hpp +++ b/src/server/events/Delete.hpp @@ -86,6 +86,8 @@ private: SharedPtr _removed_bindings; SharedPtr< Raul::Table > > _removed_table; + + Glib::RWLock::WriterLock _lock; }; } // namespace Server diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 058f0b63..61fa6ffc 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -42,12 +42,15 @@ Get::Get( , _uri(uri) , _object(NULL) , _plugin(NULL) + , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK) { } void Get::pre_process() { + _lock.acquire(); + if (_uri == "ingen:plugins") { _plugins = _engine.node_factory()->plugins(); } else if (Path::is_valid(_uri.str())) { @@ -76,6 +79,8 @@ Get::post_process() } else { _request->respond_error("Unable to find client to send object."); } + + _lock.release(); } } // namespace Server diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp index ed68e3c0..b5f1ed4d 100644 --- a/src/server/events/Get.hpp +++ b/src/server/events/Get.hpp @@ -18,6 +18,8 @@ #ifndef INGEN_EVENTS_GET_HPP #define INGEN_EVENTS_GET_HPP +#include + #include "QueuedEvent.hpp" #include "NodeFactory.hpp" #include "types.hpp" @@ -47,10 +49,11 @@ public: void post_process(); private: - const Raul::URI _uri; - GraphObjectImpl* _object; - const PluginImpl* _plugin; - NodeFactory::Plugins _plugins; + const Raul::URI _uri; + const GraphObjectImpl* _object; + const PluginImpl* _plugin; + NodeFactory::Plugins _plugins; + Glib::RWLock::ReaderLock _lock; }; } // namespace Server -- cgit v1.2.1