summaryrefslogtreecommitdiffstats
path: root/ingen
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-10 03:23:11 +0000
committerDavid Robillard <d@drobilla.net>2012-05-10 03:23:11 +0000
commitda468f24388d7f0f574c6e4dd4022e05d47a9db2 (patch)
tree32e90d5fa55a35caef43cb69592286fc31c5d4f4 /ingen
parent281bbcc6a7208c28283bc9bdd521c5d6cc48a60f (diff)
downloadingen-da468f24388d7f0f574c6e4dd4022e05d47a9db2.tar.gz
ingen-da468f24388d7f0f574c6e4dd4022e05d47a9db2.tar.bz2
ingen-da468f24388d7f0f574c6e4dd4022e05d47a9db2.zip
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
Diffstat (limited to 'ingen')
-rw-r--r--ingen/EngineBase.hpp5
-rw-r--r--ingen/Interface.hpp7
-rw-r--r--ingen/client/ThreadedSigClientInterface.hpp33
3 files changed, 41 insertions, 4 deletions
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 <stdint.h>
#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<Interface> 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<Interface> respondee() const {
+ return SharedPtr<Interface>();
+ }
+
+ virtual void set_respondee(SharedPtr<Interface> 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;