summaryrefslogtreecommitdiffstats
path: root/ingen/client/ThreadedSigClientInterface.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'ingen/client/ThreadedSigClientInterface.hpp')
-rw-r--r--ingen/client/ThreadedSigClientInterface.hpp33
1 files changed, 31 insertions, 2 deletions
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;