src/JackHandler.h
branchv_0
changeset 20 ccc4e509c1f0
parent 19 dcd98589f4b8
child 21 70b252d02a92
--- a/src/JackHandler.h	Sun Oct 04 20:42:51 2020 +0200
+++ b/src/JackHandler.h	Tue Oct 06 01:31:22 2020 +0200
@@ -177,6 +177,13 @@
 		throw JackException(errorMessage);
 	}
 
+	/**
+	 * Wait for the signal that is emitted at the end of the real-time processCallback() cycle.
+	 */
+	void waitForRTCycle() {
+		pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock);
+	}
+
 public:
 
 	JackHandler(Configuration& configuration) : configuration(configuration) {
@@ -232,7 +239,6 @@
 	void attribute(const relpipe::common::type::StringX& value) override {
 		if (relationContext.skip) return;
 		// TODO: switch to RelationalReaderValueHandler
-		// TODO: if (continueProcessing) {} ?
 
 		RelationContext& rel = relationContext;
 		RelationContext::RecordContext& rec = rel.recordContext;
@@ -252,7 +258,8 @@
 
 		if (rec.attributeIndex == rel.attributes.size()) {
 
-			while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster
+			while (continueProcessing && jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) waitForRTCycle(); // should not happen, the real-time thread should be faster; see also note in endOfPipe()
+			if (!continueProcessing) return;
 
 			MidiMessage m;
 
@@ -300,6 +307,13 @@
 
 		// Wait until the ring buffer is empty (messages dequeued from the buffer) and real-time cycle was finished (messages passed to JACK)
 		while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock);
+
+		// There might be a (rare) race condition.
+		// Between jack_ringbuffer_read_space() and pthread_cond_wait() the real-time thread might finish the cycle and we will miss the pthread_cond_signal()
+		// and will sleep until the next cycle. In endOfPipe() it is not a big problem.
+		// But missing the cycle in attribute() might be worse.
+		// However it should not happen due to the buffer size
+		// and amount of work done in the real-time thread (message copying) vs. amount of work done between the jack_ringbuffer_write_space() and pthread_cond_wait() calls (nothing).
 	}
 
 	void finish(int sig) {