summaryrefslogtreecommitdiffstats
path: root/src/server/PostProcessor.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-07-26 16:38:44 +0000
committerDavid Robillard <d@drobilla.net>2012-07-26 16:38:44 +0000
commit024d857f0dc239726cc8c042e8b9296e8886af7d (patch)
tree3591b5ac01607b8879342ea8657285f2fecc9abf /src/server/PostProcessor.cpp
parent1b38b8bc4e4e5ca9250cca15bb547ce926b0592e (diff)
downloadingen-024d857f0dc239726cc8c042e8b9296e8886af7d.tar.gz
ingen-024d857f0dc239726cc8c042e8b9296e8886af7d.tar.bz2
ingen-024d857f0dc239726cc8c042e8b9296e8886af7d.zip
Fix post processor ordering to be correctly monotonic between both pre-processed events and notifications.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4560 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server/PostProcessor.cpp')
-rw-r--r--src/server/PostProcessor.cpp30
1 files changed, 14 insertions, 16 deletions
diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp
index 16b0317d..984f69b5 100644
--- a/src/server/PostProcessor.cpp
+++ b/src/server/PostProcessor.cpp
@@ -54,34 +54,32 @@ PostProcessor::append(ProcessContext& context, Event* first, Event* last)
void
PostProcessor::process()
{
- const FrameTime end_time = _max_time.get();
+ const FrameTime end_time = _max_time.get() + 1;
- /* FIXME: The order here is a bit tricky: if the normal events are
- * processed first, then a deleted port may still have a pending
- * broadcast event which will segfault if executed afterwards.
- * If it's the other way around, broadcasts will be sent for
- * ports the client doesn't even know about yet... */
-
- /* FIXME: process events from all threads if parallel */
-
- /* Process audio thread generated events */
- _engine.process_context().emit_notifications();
+ // To avoid a race, we only process up to tail and never write to _tail
+ Event* const tail = _tail.get();
- /* Process normal events */
Event* ev = _head.get();
if (!ev) {
return;
}
- Event* const tail = _tail.get();
- _head = (Event*)tail->next();
- while (ev && ev->time() <= end_time) {
+ while (ev->time() < end_time) {
Event* const next = (Event*)ev->next();
+
+ // Process audio thread notifications up until this event's time
+ _engine.process_context().emit_notifications(ev->time());
+
+ // Process and delete this event
ev->post_process();
delete ev;
- if (ev == tail) {
+
+ if (ev == tail || next->time() >= end_time) {
+ // Reached end, update _head
+ _head = next;
break;
}
+
ev = next;
}
}