equal
deleted
inserted
replaced
175 void failInConstructor(const relpipe::common::type::StringX& errorMessage) { |
175 void failInConstructor(const relpipe::common::type::StringX& errorMessage) { |
176 finalize(); |
176 finalize(); |
177 throw JackException(errorMessage); |
177 throw JackException(errorMessage); |
178 } |
178 } |
179 |
179 |
|
180 /** |
|
181 * Wait for the signal that is emitted at the end of the real-time processCallback() cycle. |
|
182 */ |
|
183 void waitForRTCycle() { |
|
184 pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock); |
|
185 } |
|
186 |
180 public: |
187 public: |
181 |
188 |
182 JackHandler(Configuration& configuration) : configuration(configuration) { |
189 JackHandler(Configuration& configuration) : configuration(configuration) { |
183 pthread_mutex_unlock(&realTimeContext.processingLock); |
190 pthread_mutex_unlock(&realTimeContext.processingLock); |
184 |
191 |
230 } |
237 } |
231 |
238 |
232 void attribute(const relpipe::common::type::StringX& value) override { |
239 void attribute(const relpipe::common::type::StringX& value) override { |
233 if (relationContext.skip) return; |
240 if (relationContext.skip) return; |
234 // TODO: switch to RelationalReaderValueHandler |
241 // TODO: switch to RelationalReaderValueHandler |
235 // TODO: if (continueProcessing) {} ? |
|
236 |
242 |
237 RelationContext& rel = relationContext; |
243 RelationContext& rel = relationContext; |
238 RelationContext::RecordContext& rec = rel.recordContext; |
244 RelationContext::RecordContext& rec = rel.recordContext; |
239 |
245 |
240 const auto attributeName = rel.attributes[rec.attributeIndex].getAttributeName(); |
246 const auto attributeName = rel.attributes[rec.attributeIndex].getAttributeName(); |
250 |
256 |
251 rec.attributeIndex++; |
257 rec.attributeIndex++; |
252 |
258 |
253 if (rec.attributeIndex == rel.attributes.size()) { |
259 if (rec.attributeIndex == rel.attributes.size()) { |
254 |
260 |
255 while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster |
261 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() |
|
262 if (!continueProcessing) return; |
256 |
263 |
257 MidiMessage m; |
264 MidiMessage m; |
258 |
265 |
259 // TODO: correct timing? |
266 // TODO: correct timing? |
260 m.time = 0; |
267 m.time = 0; |
298 void endOfPipe() { |
305 void endOfPipe() { |
299 // TODO: optionally mute all; probably enabled by default |
306 // TODO: optionally mute all; probably enabled by default |
300 |
307 |
301 // Wait until the ring buffer is empty (messages dequeued from the buffer) and real-time cycle was finished (messages passed to JACK) |
308 // Wait until the ring buffer is empty (messages dequeued from the buffer) and real-time cycle was finished (messages passed to JACK) |
302 while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock); |
309 while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock); |
|
310 |
|
311 // There might be a (rare) race condition. |
|
312 // 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() |
|
313 // and will sleep until the next cycle. In endOfPipe() it is not a big problem. |
|
314 // But missing the cycle in attribute() might be worse. |
|
315 // However it should not happen due to the buffer size |
|
316 // 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). |
303 } |
317 } |
304 |
318 |
305 void finish(int sig) { |
319 void finish(int sig) { |
306 continueProcessing = false; |
320 continueProcessing = false; |
307 } |
321 } |