summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-12-21 02:51:35 +0000
committerDavid Robillard <d@drobilla.net>2012-12-21 02:51:35 +0000
commit853dee67639d73178f036c192ea5d98d74fb39e3 (patch)
tree3da9bd4792431ae2c8c6153729059b1c23ebd696
parentaac9cbc534ab57a5471b121523bd8308e857c228 (diff)
downloadingen-853dee67639d73178f036c192ea5d98d74fb39e3.tar.gz
ingen-853dee67639d73178f036c192ea5d98d74fb39e3.tar.bz2
ingen-853dee67639d73178f036c192ea5d98d74fb39e3.zip
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
-rw-r--r--src/server/Broadcaster.hpp25
-rw-r--r--src/server/events/Connect.cpp1
-rw-r--r--src/server/events/CreateBlock.cpp1
-rw-r--r--src/server/events/CreateGraph.cpp1
-rw-r--r--src/server/events/CreatePort.cpp1
-rw-r--r--src/server/events/Delete.cpp4
-rw-r--r--src/server/events/Delta.cpp2
-rw-r--r--src/server/events/Disconnect.cpp1
-rw-r--r--src/server/events/DisconnectAll.cpp1
-rw-r--r--src/server/events/Get.cpp3
-rw-r--r--src/server/events/Move.cpp1
-rw-r--r--src/server/events/SetPortValue.cpp1
12 files changed, 38 insertions, 4 deletions
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<Interface> 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<Interface> 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<Interface> > 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<const PortImpl*>(_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(),