summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd/event_loop.h
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-12-28 10:14:17 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2015-12-28 10:14:17 -0500
commit0d9efc11484c901795ff4e9549a1a39715d0474d (patch)
tree956ab3cd570670bcb1ff68856553f5aec4a8e470 /libs/pbd/pbd/event_loop.h
parentdb4834027858b10f313c822c7fb3fad1617f11aa (diff)
redesign cross-thread registration/signalling system
This new design will work even when threads that need to receive messages from RT threads are created *after* the RT threads. The existing design would fail because the RT thread(s) would never be known the later created threads, and so signals emitted by the RT thread and causing call_slot() in the receiver would end up being enqueued using a lock-protected list. The new design ensures that communication always uses a lock-free FIFO instead
Diffstat (limited to 'libs/pbd/pbd/event_loop.h')
-rw-r--r--libs/pbd/pbd/event_loop.h33
1 files changed, 33 insertions, 0 deletions
diff --git a/libs/pbd/pbd/event_loop.h b/libs/pbd/pbd/event_loop.h
index 3ea6388f3f..90d72ef47c 100644
--- a/libs/pbd/pbd/event_loop.h
+++ b/libs/pbd/pbd/event_loop.h
@@ -21,6 +21,8 @@
#define __pbd_event_loop_h__
#include <string>
+#include <vector>
+#include <map>
#include <boost/function.hpp>
#include <boost/bind.hpp> /* we don't need this here, but anything calling call_slot() probably will, so this is convenient */
#include <glibmm/threads.h>
@@ -79,9 +81,40 @@ class LIBPBD_API EventLoop
static EventLoop* get_event_loop_for_thread();
static void set_event_loop_for_thread (EventLoop* ui);
+ struct ThreadBufferMapping {
+ pthread_t emitting_thread;
+ std::string target_thread_name;
+ void* request_buffer;
+ };
+
+ static std::vector<ThreadBufferMapping> get_request_buffers_for_target_thread (const std::string&);
+
+ static void register_request_buffer_factory (const std::string& target_thread_name, void* (*factory) (uint32_t));
+ static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
+
private:
static Glib::Threads::Private<EventLoop> thread_event_loop;
std::string _name;
+
+ typedef std::map<std::string,ThreadBufferMapping> ThreadRequestBufferList;
+ static ThreadRequestBufferList thread_buffer_requests;
+ static Glib::Threads::RWLock thread_buffer_requests_lock;
+
+ struct RequestBufferSupplier {
+
+ /* @param name : name of object/entity that will/may accept
+ requests from other threads, via a request buffer.
+ */
+ std::string name;
+
+ /* @param factory : a function that can be called (with an
+ argument specifying the @param number_of_requests) to create and
+ return a request buffer for communicating with @param name)
+ */
+ void* (*factory)(uint32_t nunber_of_requests);
+ };
+ typedef std::vector<RequestBufferSupplier> RequestBufferSuppliers;
+ static RequestBufferSuppliers request_buffer_suppliers;
};
}