From 853dee67639d73178f036c192ea5d98d74fb39e3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 21 Dec 2012 02:51:35 +0000 Subject: Add Broadcaster::Transfer for scoped recursion-safe reply bundling. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4868 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/Broadcaster.hpp | 25 +++++++++++++++++++++++++ src/server/events/Connect.cpp | 1 + src/server/events/CreateBlock.cpp | 1 + src/server/events/CreateGraph.cpp | 1 + src/server/events/CreatePort.cpp | 1 + src/server/events/Delete.cpp | 4 ++-- src/server/events/Delta.cpp | 2 ++ src/server/events/Disconnect.cpp | 1 + src/server/events/DisconnectAll.cpp | 1 + src/server/events/Get.cpp | 3 +-- src/server/events/Move.cpp | 1 + src/server/events/SetPortValue.cpp | 1 + 12 files changed, 38 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/Broadcaster.hpp b/src/server/Broadcaster.hpp index 3af4e5b7..621b6b61 100644 --- a/src/server/Broadcaster.hpp +++ b/src/server/Broadcaster.hpp @@ -42,9 +42,31 @@ namespace Server { class Broadcaster : public Interface { public: + Broadcaster() : _bundle_depth(0) {} + void register_client(const Raul::URI& uri, SharedPtr client); bool unregister_client(const Raul::URI& uri); + /** A handle that represents a transfer of possibly several changes. + * + * This object going out of scope signifies the transfer is completed. + * This makes doing the right thing in recursive functions that send + * updates simple (e.g. Event::post_process()). + */ + struct Transfer : public Raul::Noncopyable { + Transfer(Broadcaster& b) : broadcaster(b) { + if (++broadcaster._bundle_depth == 1) { + broadcaster.bundle_begin(); + } + } + ~Transfer() { + if (--broadcaster._bundle_depth == 0) { + broadcaster.bundle_end(); + } + } + Broadcaster& broadcaster; + }; + SharedPtr client(const Raul::URI& uri); void send_plugins(const BlockFactory::Plugins& plugin_list); @@ -109,10 +131,13 @@ public: void error(const std::string& msg) { BROADCAST(error, msg); } private: + friend class Transfer; + typedef std::map< Raul::URI, SharedPtr > Clients; Glib::Mutex _clients_mutex; Clients _clients; + unsigned _bundle_depth; }; } // namespace Server diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp index 5e749628..e0d1b091 100644 --- a/src/server/events/Connect.cpp +++ b/src/server/events/Connect.cpp @@ -154,6 +154,7 @@ Connect::execute(ProcessContext& context) void Connect::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->connect(_tail_path, _head_path); } diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp index bc234b97..4c6fda5c 100644 --- a/src/server/events/CreateBlock.cpp +++ b/src/server/events/CreateBlock.cpp @@ -132,6 +132,7 @@ CreateBlock::execute(ProcessContext& context) void CreateBlock::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { for (Update::const_iterator i = _update.begin(); i != _update.end(); ++i) { _engine.broadcaster()->put(i->first, i->second); diff --git a/src/server/events/CreateGraph.cpp b/src/server/events/CreateGraph.cpp index c16c120c..c55acd87 100644 --- a/src/server/events/CreateGraph.cpp +++ b/src/server/events/CreateGraph.cpp @@ -111,6 +111,7 @@ CreateGraph::execute(ProcessContext& context) void CreateGraph::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->put(Node::path_to_uri(_path), _update); } diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp index 58402014..624802f3 100644 --- a/src/server/events/CreatePort.cpp +++ b/src/server/events/CreatePort.cpp @@ -184,6 +184,7 @@ CreatePort::execute(ProcessContext& context) void CreatePort::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->put(Node::path_to_uri(_path), _update); } diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index 2504e837..a1d96960 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -144,17 +144,17 @@ Delete::post_process() { _lock.release(); _removed_bindings.reset(); + + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond() && (_block || _port)) { if (_block) { _block->deactivate(); } - _engine.broadcaster()->bundle_begin(); if (_disconnect_event) { _disconnect_event->post_process(); } _engine.broadcaster()->del(_uri); - _engine.broadcaster()->bundle_end(); } if (_engine_port) { diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 1c823cdd..f22a928f 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -344,6 +344,8 @@ Delta::execute(ProcessContext& context) void Delta::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); + for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) (*i)->post_process(); diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp index 65c5b078..355d90c8 100644 --- a/src/server/events/Disconnect.cpp +++ b/src/server/events/Disconnect.cpp @@ -212,6 +212,7 @@ Disconnect::execute(ProcessContext& context) void Disconnect::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->disconnect(_tail_path, _head_path); } diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp index 1548c5e1..f96fd4d7 100644 --- a/src/server/events/DisconnectAll.cpp +++ b/src/server/events/DisconnectAll.cpp @@ -161,6 +161,7 @@ DisconnectAll::execute(ProcessContext& context) void DisconnectAll::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->disconnect_all(_parent_path, _path); } diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 1493f161..949e8c49 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -129,6 +129,7 @@ send_graph(Interface* client, const GraphImpl* graph) void Get::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond() && _request_client) { if (_uri == "ingen:plugins") { _engine.broadcaster()->send_plugins_to(_request_client.get(), _plugins); @@ -140,7 +141,6 @@ Get::post_process() uris.ingen_sampleRate, uris.forge.make(int32_t(_engine.driver()->sample_rate()))); } else if (_object) { - _request_client->bundle_begin(); const BlockImpl* block = NULL; const GraphImpl* graph = NULL; const PortImpl* port = NULL; @@ -151,7 +151,6 @@ Get::post_process() } else if ((port = dynamic_cast(_object))) { send_port(_request_client.get(), port); } - _request_client->bundle_end(); } else if (_plugin) { _request_client->put(_uri, _plugin->properties()); } diff --git a/src/server/events/Move.cpp b/src/server/events/Move.cpp index 58f47e13..08eea56a 100644 --- a/src/server/events/Move.cpp +++ b/src/server/events/Move.cpp @@ -83,6 +83,7 @@ Move::execute(ProcessContext& context) void Move::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->move(_old_path, _new_path); } diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp index 7a994caa..14919cee 100644 --- a/src/server/events/SetPortValue.cpp +++ b/src/server/events/SetPortValue.cpp @@ -112,6 +112,7 @@ SetPortValue::apply(Context& context) void SetPortValue::post_process() { + Broadcaster::Transfer t(*_engine.broadcaster()); if (!respond()) { _engine.broadcaster()->set_property( _port->uri(), -- cgit v1.2.1