From da468f24388d7f0f574c6e4dd4022e05d47a9db2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 10 May 2012 03:23:11 +0000 Subject: Use SharedPtr references to Interfaces to keep things sane. Fix double register when using GUI with a remote engine. Avoid signal when writing to dead socket by using send with MSG_NOSIGNAL. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4336 a436a847-0d15-0410-975c-d299462d15a1 --- ingen/EngineBase.hpp | 5 +++-- ingen/Interface.hpp | 7 ++++++ ingen/client/ThreadedSigClientInterface.hpp | 33 +++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) (limited to 'ingen') diff --git a/ingen/EngineBase.hpp b/ingen/EngineBase.hpp index df65c5d0..51af6de5 100644 --- a/ingen/EngineBase.hpp +++ b/ingen/EngineBase.hpp @@ -20,6 +20,7 @@ #include #include "raul/URI.hpp" +#include "raul/SharedPtr.hpp" namespace Ingen { @@ -74,8 +75,8 @@ public: /** Register a client to receive updates about engine changes. */ - virtual void register_client(const Raul::URI& uri, - Interface* client) = 0; + virtual void register_client(const Raul::URI& uri, + SharedPtr client) = 0; /** Unregister a client. diff --git a/ingen/Interface.hpp b/ingen/Interface.hpp index 0a3411a1..96a438a9 100644 --- a/ingen/Interface.hpp +++ b/ingen/Interface.hpp @@ -19,6 +19,7 @@ #include "ingen/Resource.hpp" #include "ingen/Status.hpp" +#include "raul/SharedPtr.hpp" namespace Raul { class Atom; @@ -40,6 +41,12 @@ public: virtual Raul::URI uri() const = 0; + virtual SharedPtr respondee() const { + return SharedPtr(); + } + + virtual void set_respondee(SharedPtr respondee) {} + /** Begin an atomic bundle */ virtual void bundle_begin() = 0; diff --git a/ingen/client/ThreadedSigClientInterface.hpp b/ingen/client/ThreadedSigClientInterface.hpp index 096920bd..e8b46504 100644 --- a/ingen/client/ThreadedSigClientInterface.hpp +++ b/ingen/client/ThreadedSigClientInterface.hpp @@ -106,10 +106,39 @@ public: { push_sig(sigc::bind(property_change_slot, subject, key, value)); } /** Process all queued events - Called from GTK thread to emit signals. */ - bool emit_signals(); + bool emit_signals() { + // Process a limited number of events, to prevent locking the GTK + // thread indefinitely while processing continually arriving events + + size_t num_processed = 0; + while (!_sigs.empty() && num_processed++ < (_sigs.capacity() * 3 / 4)) { + Closure& ev = _sigs.front(); + ev(); + ev.disconnect(); + _sigs.pop(); + } + + _mutex.lock(); + _cond.broadcast(); + _mutex.unlock(); + + return true; + } private: - void push_sig(Closure ev); + void push_sig(Closure ev) { + bool success = false; + while (!success) { + success = _sigs.push(ev); + if (!success) { + Raul::warn << "Client event queue full. Waiting..." << std::endl; + _mutex.lock(); + _cond.wait(_mutex); + _mutex.unlock(); + Raul::warn << "Queue drained, continuing" << std::endl; + } + } + } Glib::Mutex _mutex; Glib::Cond _cond; -- cgit v1.2.1