From 22209796627acfef17c53d4cf523eed3daa26c2b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 15 May 2012 01:52:08 +0000 Subject: Eliminate long-duration event locks by generated responses in pre_process(). This also fixes some correctness issues, since the state at pre_process() time is actually the state that needs to be broadcast to clients. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4416 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/events/CreateNode.cpp | 18 +++++++++++++++--- src/server/events/CreateNode.hpp | 22 +++++++++++++--------- src/server/events/CreatePatch.cpp | 8 ++++---- src/server/events/CreatePatch.hpp | 12 ++++++------ src/server/events/CreatePort.cpp | 6 ++++-- src/server/events/CreatePort.hpp | 1 + src/server/events/Get.cpp | 19 +++++++++---------- src/server/events/SetMetadata.cpp | 15 ++++----------- src/server/events/SetMetadata.hpp | 7 ------- 9 files changed, 56 insertions(+), 52 deletions(-) diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp index b2a6a995..87ecd657 100644 --- a/src/server/events/CreateNode.cpp +++ b/src/server/events/CreateNode.cpp @@ -45,13 +45,13 @@ CreateNode::CreateNode(Engine& engine, : Event(engine, client, id, timestamp) , _path(path) , _plugin_uri(plugin_uri) + , _properties(properties) , _patch(NULL) , _plugin(NULL) , _node(NULL) , _compiled_patch(NULL) , _node_already_exists(false) , _polyphonic(false) - , _properties(properties) { const Resource::Properties::const_iterator p = properties.find( engine.world()->uris().ingen_polyphonic); @@ -92,7 +92,17 @@ CreateNode::pre_process() } } - if (!_node) { + if (_node) { + Ingen::Shared::URIs& uris = _engine.world()->uris(); + _update.push_back(make_pair(_node->path(), _node->properties())); + for (uint32_t i = 0; i < _node->num_ports(); ++i) { + const PortImpl* port = _node->port_impl(i); + Resource::Properties pprops = port->properties(); + pprops.erase(uris.ingen_value); + pprops.insert(std::make_pair(uris.ingen_value, port->value())); + _update.push_back(std::make_pair(port->path(), pprops)); + } + } else { _status = FAILURE; } @@ -123,7 +133,9 @@ CreateNode::post_process() respond(FAILURE); } else { respond(SUCCESS); - _engine.broadcaster()->send_object(_node, true); // yes, send ports + for (Update::const_iterator i = _update.begin(); i != _update.end(); ++i) { + _engine.broadcaster()->put(i->first, i->second); + } } } diff --git a/src/server/events/CreateNode.hpp b/src/server/events/CreateNode.hpp index 2b3e008b..b3b84abf 100644 --- a/src/server/events/CreateNode.hpp +++ b/src/server/events/CreateNode.hpp @@ -17,7 +17,8 @@ #ifndef INGEN_EVENTS_CREATENODE_HPP #define INGEN_EVENTS_CREATENODE_HPP -#include +#include +#include #include "ingen/Resource.hpp" @@ -53,16 +54,19 @@ public: void post_process(); private: - Raul::Path _path; - Raul::URI _plugin_uri; - PatchImpl* _patch; - PluginImpl* _plugin; - NodeImpl* _node; - CompiledPatch* _compiled_patch; ///< Patch's new process order - bool _node_already_exists; - bool _polyphonic; + /// Update put message to broadcast to clients + typedef std::list< std::pair > Update; + Raul::Path _path; + Raul::URI _plugin_uri; Resource::Properties _properties; + Update _update; + PatchImpl* _patch; + PluginImpl* _plugin; + NodeImpl* _node; + CompiledPatch* _compiled_patch; ///< Patch's new process order + bool _node_already_exists; + bool _polyphonic; }; } // namespace Events diff --git a/src/server/events/CreatePatch.cpp b/src/server/events/CreatePatch.cpp index 68359a5b..8bb381a2 100644 --- a/src/server/events/CreatePatch.cpp +++ b/src/server/events/CreatePatch.cpp @@ -40,11 +40,11 @@ CreatePatch::CreatePatch(Engine& engine, const Resource::Properties& properties) : Event(engine, client, id, timestamp) , _path(path) + , _properties(properties) , _patch(NULL) , _parent(NULL) , _compiled_patch(NULL) , _poly(poly) - , _properties(properties) { } @@ -97,6 +97,8 @@ CreatePatch::pre_process() // Insert into EngineStore _engine.engine_store()->add(_patch); + _update = _patch->properties(); + Event::pre_process(); } @@ -118,9 +120,7 @@ CreatePatch::post_process() { respond(_status); if (!_status) { - // Don't send ports/nodes that have been added since prepare() - // (otherwise they would be sent twice) - _engine.broadcaster()->send_object(_patch, false); + _engine.broadcaster()->put(_path, _update); } } diff --git a/src/server/events/CreatePatch.hpp b/src/server/events/CreatePatch.hpp index 355a4698..0747ec06 100644 --- a/src/server/events/CreatePatch.hpp +++ b/src/server/events/CreatePatch.hpp @@ -48,13 +48,13 @@ public: void post_process(); private: - const Raul::Path _path; - PatchImpl* _patch; - PatchImpl* _parent; - CompiledPatch* _compiled_patch; - int _poly; - + const Raul::Path _path; Resource::Properties _properties; + Resource::Properties _update; + PatchImpl* _patch; + PatchImpl* _parent; + CompiledPatch* _compiled_patch; + int _poly; }; } // namespace Events diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp index c4ba0a3b..d8c183cd 100644 --- a/src/server/events/CreatePort.cpp +++ b/src/server/events/CreatePort.cpp @@ -134,7 +134,6 @@ CreatePort::pre_process() assert(index_i->second == _engine.world()->forge().make((int)_patch_port->index())); if (_patch_port) { - if (_is_output) _patch->add_output(new Raul::List::Node(_patch_port)); else @@ -159,6 +158,9 @@ CreatePort::pre_process() _status = CREATION_FAILED; } } + + _update = _patch_port->properties(); + Event::pre_process(); } @@ -182,7 +184,7 @@ CreatePort::post_process() { respond(_status); if (!_status) { - _engine.broadcaster()->send_object(_patch_port, true); + _engine.broadcaster()->put(_path, _update); } } diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp index 6050cc18..25f8ba9b 100644 --- a/src/server/events/CreatePort.hpp +++ b/src/server/events/CreatePort.hpp @@ -63,6 +63,7 @@ private: Raul::Array* _ports_array; ///< New (external) ports array for Patch EnginePort* _engine_port; ///< Driver (eg Jack) port if this is a toplevel port Resource::Properties _properties; + Resource::Properties _update; bool _is_output; }; diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 7e140ae4..ac8db196 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -77,18 +77,17 @@ Get::post_process() } } else if (!_object && !_plugin) { respond(NOT_FOUND); - } else if (_request_client) { - respond(SUCCESS); - if (_request_client) { - if (_object) { - ObjectSender::send_object(_request_client, _object, true); - } else if (_plugin) { - _request_client->put(_uri, _plugin->properties()); - } - } - } else { + } else if (!_request_client) { respond(CLIENT_NOT_FOUND); } + + respond(SUCCESS); + + if (_object) { + ObjectSender::send_object(_request_client, _object, true); + } else if (_plugin) { + _request_client->put(_uri, _plugin->properties()); + } _lock.release(); } diff --git a/src/server/events/SetMetadata.cpp b/src/server/events/SetMetadata.cpp index fa02f220..26757426 100644 --- a/src/server/events/SetMetadata.cpp +++ b/src/server/events/SetMetadata.cpp @@ -17,6 +17,8 @@ #include #include +#include + #include #include "raul/log.hpp" @@ -68,7 +70,6 @@ SetMetadata::SetMetadata(Engine& engine, , _compiled_patch(NULL) , _create(create) , _context(context) - , _lock(engine.engine_store()->lock(), Glib::NOT_LOCK) { if (context != Resource::DEFAULT) { Resource::set_context(_properties, context); @@ -107,7 +108,8 @@ SetMetadata::pre_process() const bool is_graph_object = Raul::Path::is_path(_subject); - _lock.acquire(); + // Take a writer lock while we modify the store + Glib::RWLock::WriterLock lock(_engine.engine_store()->lock()); _object = is_graph_object ? _engine.engine_store()->find_object(Raul::Path(_subject.str())) @@ -251,17 +253,12 @@ SetMetadata::pre_process() } if (_status != SUCCESS) { - _error_predicate += key.str(); break; } _types.push_back(op); } - if (!_create_event) { - _lock.release(); - } - Event::pre_process(); } @@ -367,10 +364,6 @@ SetMetadata::post_process() } else { respond(_status); } - - if (_create_event) { - _lock.release(); - } } } // namespace Events diff --git a/src/server/events/SetMetadata.hpp b/src/server/events/SetMetadata.hpp index 7f5d82b4..84957e02 100644 --- a/src/server/events/SetMetadata.hpp +++ b/src/server/events/SetMetadata.hpp @@ -17,10 +17,6 @@ #ifndef INGEN_EVENTS_SETMETADATA_HPP #define INGEN_EVENTS_SETMETADATA_HPP -#include - -#include - #include #include "raul/URI.hpp" @@ -108,14 +104,11 @@ private: Ingen::Shared::ResourceImpl* _object; PatchImpl* _patch; CompiledPatch* _compiled_patch; - std::string _error_predicate; bool _create; Resource::Graph _context; ControlBindings::Key _binding; SharedPtr _old_bindings; - - Glib::RWLock::WriterLock _lock; }; } // namespace Events -- cgit v1.2.1