diff --git a/src/jack-audio-module.cc b/src/jack-audio-module.cc index 76721e6..ed2c5a3 100644 --- a/src/jack-audio-module.cc +++ b/src/jack-audio-module.cc @@ -87,6 +87,8 @@ void JackAudioModule::wipe_buffers() { } void JackAudioModule::globally_register() { + std::unique_lock lock(g_audio_modules_mutex); + g_audio_modules.push_back(this); /* ensure modules are not filling up their buffers out of sync */ @@ -99,6 +101,8 @@ void JackAudioModule::globally_register() { } void JackAudioModule::globally_unregister() { + std::unique_lock lock(g_audio_modules_mutex); + /* drop ourselves from active module list */ auto x = std::find(g_audio_modules.begin(), g_audio_modules.end(), this); if (x != g_audio_modules.end()) diff --git a/src/skjack.cc b/src/skjack.cc index a10df0c..f415f52 100644 --- a/src/skjack.cc +++ b/src/skjack.cc @@ -9,11 +9,14 @@ std::condition_variable g_jack_cv; // this would be optimal for correctness, but in practice this gets modified // very infrequently and nobody cares if we miss one or two audio frames right // after creating or destroying a module... +std::mutex g_audio_modules_mutex; std::vector g_audio_modules; std::atomic g_audio_blocked(0); int on_jack_process(jack_nframes_t nframes, void *) { if (!g_jack_client.alive()) return 1; + /* audio modules vector is blocked; we have to skip this cycle */ + if (!g_audio_modules_mutex.try_lock()) return 0; for (auto itr = g_audio_modules.begin(); itr != g_audio_modules.end(); @@ -46,6 +49,8 @@ int on_jack_process(jack_nframes_t nframes, void *) { } g_audio_blocked = 0; + g_audio_modules_mutex.unlock(); + g_jack_cv.notify_all(); return 0; } diff --git a/src/skjack.hh b/src/skjack.hh index a75c699..b17148b 100644 --- a/src/skjack.hh +++ b/src/skjack.hh @@ -27,6 +27,7 @@ extern std::condition_variable g_jack_cv; // We'll be using this from here on out. extern jaq::client g_jack_client; +extern std::mutex g_audio_modules_mutex; extern std::vector g_audio_modules; extern std::atomic g_audio_blocked;