# HG changeset patch # User František Kučera # Date 1601836971 -7200 # Node ID dcd98589f4b82a6580018c48dc28dc0de38ae29c # Parent 7a74e9f9e67447fd6917b776b9133a5a4553de00 use signal instead of sleep while waiting at the end diff -r 7a74e9f9e674 -r dcd98589f4b8 src/CMakeLists.txt --- a/src/CMakeLists.txt Sun Oct 04 19:59:03 2020 +0200 +++ b/src/CMakeLists.txt Sun Oct 04 20:42:51 2020 +0200 @@ -34,7 +34,7 @@ ) # Link libraries: -target_link_libraries(${EXECUTABLE_FILE} ${RELPIPE_LIBS_LIBRARIES}) +target_link_libraries(${EXECUTABLE_FILE} ${RELPIPE_LIBS_LIBRARIES} pthread) set_property(TARGET ${EXECUTABLE_FILE} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) install(TARGETS ${EXECUTABLE_FILE} DESTINATION bin) diff -r 7a74e9f9e674 -r dcd98589f4b8 src/JackHandler.h --- a/src/JackHandler.h Sun Oct 04 19:59:03 2020 +0200 +++ b/src/JackHandler.h Sun Oct 04 20:42:51 2020 +0200 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,9 @@ jack_port_t* jackPort = nullptr; jack_ringbuffer_t* ringBuffer = nullptr; + pthread_mutex_t processingLock = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t processingDone = PTHREAD_COND_INITIALIZER; + const int RING_BUFFER_SIZE = 100; int processCallback(jack_nframes_t frames) { @@ -86,11 +90,16 @@ jack_midi_data_t* midiData = jack_midi_event_reserve(jackPortBuffer, m.time, m.size); memcpy(midiData, m.buffer, m.size); } + + if (pthread_mutex_trylock(&processingLock) == 0) { + pthread_cond_signal(&processingDone); + pthread_mutex_unlock(&processingLock); + } + return 0; } int syncCallback(jack_transport_state_t state, jack_position_t* position) { - std::wcerr << L"syncCallback()" << std::endl; return true; } @@ -160,6 +169,7 @@ jack_deactivate(realTimeContext.jackClient); jack_client_close(realTimeContext.jackClient); jack_ringbuffer_free(realTimeContext.ringBuffer); + pthread_mutex_unlock(&realTimeContext.processingLock); } void failInConstructor(const relpipe::common::type::StringX& errorMessage) { @@ -170,6 +180,8 @@ public: JackHandler(Configuration& configuration) : configuration(configuration) { + pthread_mutex_unlock(&realTimeContext.processingLock); + // Initialize JACK connection: std::string clientName = convertor.to_bytes(configuration.jackClientName); realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr); @@ -284,11 +296,10 @@ } void endOfPipe() { - // Wait until the ring buffer is empty - while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) usleep(1000); - usleep(1000000); - // TODO: better waiting (ringBuffer might be empty, but events have not been sent to JACK yet) // TODO: optionally mute all; probably enabled by default + + // 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); } void finish(int sig) {