summaryrefslogtreecommitdiffstats
path: root/src/engine/MessageContext.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-11-22 05:13:47 +0000
committerDavid Robillard <d@drobilla.net>2009-11-22 05:13:47 +0000
commit1745a63b874c296253a27ca7ad95d3a7b17822f7 (patch)
tree63bb78f0c34372f70634ea6122d83ed07019dc88 /src/engine/MessageContext.hpp
parente479da3c26d41e977cf55b8e2355db45991be09f (diff)
downloadingen-1745a63b874c296253a27ca7ad95d3a7b17822f7.tar.gz
ingen-1745a63b874c296253a27ca7ad95d3a7b17822f7.tar.bz2
ingen-1745a63b874c296253a27ca7ad95d3a7b17822f7.zip
Execute cross-context events in correct increasing time order.
Propagate value changes / message sends breadth first instead of deptch first. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2282 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/MessageContext.hpp')
-rw-r--r--src/engine/MessageContext.hpp50
1 files changed, 40 insertions, 10 deletions
diff --git a/src/engine/MessageContext.hpp b/src/engine/MessageContext.hpp
index c871ad1c..4d8c0695 100644
--- a/src/engine/MessageContext.hpp
+++ b/src/engine/MessageContext.hpp
@@ -18,12 +18,14 @@
#ifndef MESSAGECONTEXT_H
#define MESSAGECONTEXT_H
+#include <set>
#include <glibmm/thread.h>
#include "raul/Thread.hpp"
#include "raul/Semaphore.hpp"
#include "raul/AtomicPtr.hpp"
#include "object.lv2/object.h"
#include "Context.hpp"
+#include "ProcessContext.hpp"
#include "ThreadManager.hpp"
#include "tuning.hpp"
@@ -48,19 +50,37 @@ public:
, Raul::Thread("message-context")
, _sem(0)
, _requests(message_context_queue_size)
+ , _end_time(0)
{
Thread::set_context(THREAD_MESSAGE);
}
/** Request a run starting at node.
- *
* Safe to call from either process thread or pre-process thread.
*/
- void run(NodeImpl* node);
+ void run(NodeImpl* node, FrameTime time);
- inline void signal() { _sem.post(); }
+protected:
+ struct Request {
+ Request(FrameTime t=0, NodeImpl* n=0) : time(t), node(n) {}
+ FrameTime time;
+ NodeImpl* node;
+ };
+
+public:
+ /** Signal the end of a cycle that has produced messages.
+ * AUDIO THREAD ONLY.
+ */
+ inline void signal(ProcessContext& context) {
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+ const Request cycle_end_request(context.end(), NULL);
+ _requests.write(sizeof(Request), &cycle_end_request);
+ _sem.post();
+ }
+
+ /** Return true iff requests are pending. Safe from any thread. */
inline bool has_requests() const {
- return _requests.read_space() >= sizeof(NodeImpl*) || _request.get();
+ return _requests.read_space() >= sizeof(Request);
}
protected:
@@ -68,13 +88,23 @@ protected:
void _run();
/** Actually execute and propagate from node */
- void run_node(NodeImpl* node);
+ void execute(const Request& req);
+
+ Raul::Semaphore _sem;
+ Raul::RingBuffer<Request> _requests;
+ Glib::Mutex _mutex;
+ Glib::Cond _cond;
+ Request _non_rt_request;
+
+ struct RequestEarlier {
+ bool operator()(const Request& r1, const Request& r2) {
+ return r1.time < r2.time;
+ }
+ };
- Raul::Semaphore _sem;
- Raul::RingBuffer<NodeImpl*> _requests;
- Glib::Mutex _mutex;
- Glib::Cond _cond;
- Raul::AtomicPtr<NodeImpl> _request;
+ typedef std::set<Request, RequestEarlier> Queue;
+ Queue _queue;
+ FrameTime _end_time;
};