diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2015-12-28 10:14:17 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2015-12-28 10:14:17 -0500 |
commit | 0d9efc11484c901795ff4e9549a1a39715d0474d (patch) | |
tree | 956ab3cd570670bcb1ff68856553f5aec4a8e470 /libs/pbd/pbd/event_loop.h | |
parent | db4834027858b10f313c822c7fb3fad1617f11aa (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.h | 33 |
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; }; } |