diff options
author | David Robillard <d@drobilla.net> | 2017-12-16 12:42:04 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2017-12-16 13:57:39 +0100 |
commit | b7341fdcb0f10025b725172d7b95ba5b1294b9d3 (patch) | |
tree | edc5b0722f14cb835a91daf666b3a0ff5140cf73 | |
parent | d1977ed28176c5d2a8d065ad3731af486e83acb4 (diff) | |
download | ingen-b7341fdcb0f10025b725172d7b95ba5b1294b9d3.tar.gz ingen-b7341fdcb0f10025b725172d7b95ba5b1294b9d3.tar.bz2 ingen-b7341fdcb0f10025b725172d7b95ba5b1294b9d3.zip |
Use unbounded queue for client signals
-rw-r--r-- | ingen/client/ThreadedSigClientInterface.hpp | 46 | ||||
-rw-r--r-- | src/gui/ConnectWindow.cpp | 2 | ||||
-rw-r--r-- | src/ingen/ingen.cpp | 2 |
3 files changed, 18 insertions, 32 deletions
diff --git a/ingen/client/ThreadedSigClientInterface.hpp b/ingen/client/ThreadedSigClientInterface.hpp index 219fd8d1..96c47374 100644 --- a/ingen/client/ThreadedSigClientInterface.hpp +++ b/ingen/client/ThreadedSigClientInterface.hpp @@ -17,19 +17,18 @@ #ifndef INGEN_CLIENT_THREADEDSIGCLIENTINTERFACE_HPP #define INGEN_CLIENT_THREADEDSIGCLIENTINTERFACE_HPP -#include <stdint.h> - +#include <cstdint> +#include <mutex> #include <string> +#include <vector> #undef nil #include <sigc++/sigc++.h> -#include <glibmm/thread.h> #include "ingen/Atom.hpp" #include "ingen/Interface.hpp" #include "ingen/client/SigClientInterface.hpp" #include "ingen/ingen.h" -#include "raul/SRSWQueue.hpp" /** Returns nothing and takes no parameters (because they have all been bound) */ typedef sigc::slot<void> Closure; @@ -52,9 +51,8 @@ namespace Client { class INGEN_API ThreadedSigClientInterface : public SigClientInterface { public: - explicit ThreadedSigClientInterface(uint32_t queue_size) - : _sigs(queue_size) - , response_slot(_signal_response.make_slot()) + ThreadedSigClientInterface() + : response_slot(_signal_response.make_slot()) , error_slot(_signal_error.make_slot()) , put_slot(_signal_put.make_slot()) , connection_slot(_signal_connection.make_slot()) @@ -117,41 +115,29 @@ public: /** Process all queued events - Called from GTK thread to emit signals. */ bool emit_signals() { - // Process a limited number of events, to prevent locking the GTK - // thread indefinitely while processing continually arriving events + // Get pending signals + std::vector<Closure> sigs; + { + std::lock_guard<std::mutex> lock(_mutex); + std::swap(sigs, _sigs); + } - size_t num_processed = 0; - while (!_sigs.empty() && num_processed++ < (_sigs.capacity() * 3 / 4)) { - Closure& ev = _sigs.front(); + for (auto& ev : sigs) { ev(); ev.disconnect(); - _sigs.pop(); } - _mutex.lock(); - _cond.broadcast(); - _mutex.unlock(); - return true; } private: void push_sig(Closure ev) { - bool success = false; - while (!success) { - success = _sigs.push(ev); - if (!success) { - _mutex.lock(); - _cond.wait(_mutex); - _mutex.unlock(); - } - } + std::lock_guard<std::mutex> lock(_mutex); + _sigs.push_back(ev); } - Glib::Mutex _mutex; - Glib::Cond _cond; - - Raul::SRSWQueue<Closure> _sigs; + std::mutex _mutex; + std::vector<Closure> _sigs; using Graph = Resource::Graph; using Path = Raul::Path; diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp index 1aea8b26..f719cdc1 100644 --- a/src/gui/ConnectWindow.cpp +++ b/src/gui/ConnectWindow.cpp @@ -183,7 +183,7 @@ ConnectWindow::connect_remote(const Raul::URI& uri) Ingen::World* world = _app->world(); SPtr<ThreadedSigClientInterface> tsci( - new Client::ThreadedSigClientInterface(1024)); + new Client::ThreadedSigClientInterface()); SPtr<Ingen::Interface> iface(world->new_interface(uri, tsci)); if (iface) { diff --git a/src/ingen/ingen.cpp b/src/ingen/ingen.cpp index b6831a9c..8adc1fe2 100644 --- a/src/ingen/ingen.cpp +++ b/src/ingen/ingen.cpp @@ -135,7 +135,7 @@ main(int argc, char** argv) const char* const uri = conf.option("connect").ptr<char>(); ingen_try(Raul::URI::is_valid(uri), (fmt("Invalid URI <%1%>") % uri).str().c_str()); - SPtr<Interface> client(new Client::ThreadedSigClientInterface(1024)); + SPtr<Interface> client(new Client::ThreadedSigClientInterface()); engine_interface = world->new_interface(Raul::URI(uri), client); if (!engine_interface && !conf.option("gui").get<int32_t>()) { |