From 235ad6fbbce2e0ae9e06db960a5ba3b099936ace Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 22 Jan 2022 20:42:50 +0100 Subject: Prevent processing jack clients that are being deleted. --- drumgizmo/jackclient.cc | 48 ++++++++++++++++++++++++++++++++++++------------ drumgizmo/jackclient.h | 12 +++++++++--- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/drumgizmo/jackclient.cc b/drumgizmo/jackclient.cc index 8bf0939..0b05358 100644 --- a/drumgizmo/jackclient.cc +++ b/drumgizmo/jackclient.cc @@ -28,12 +28,6 @@ #include "jackclient.h" -JackProcess::~JackProcess() -{ -} - -// -------------------------------------------------------------------- - JackPort::JackPort(JackClient& client, const std::string& name, const char* type, JackPortFlags flags) : client{client.client} // register jack port for given client @@ -57,8 +51,7 @@ int JackClient::wrapJackProcess(jack_nframes_t nframes, void* arg) return static_cast(arg)->process(nframes); } -void JackClient::latencyCallback(jack_latency_callback_mode_t mode, - void* arg) +void JackClient::latencyCallback(jack_latency_callback_mode_t mode, void* arg) { static_cast(arg)->jackLatencyCallback(mode); } @@ -92,12 +85,23 @@ JackClient::~JackClient() void JackClient::add(JackProcess& process) { - processes.insert(&process); + JackProcessContainer c; + c.process = &process; + processes.push_back(std::move(c)); } void JackClient::remove(JackProcess& process) { - processes.erase(&process); + // Do not erase here. Instead mark as disabled - it will be erased at next + // JackClient::process call. + for(auto& ptr : processes) + { + if(ptr.process == &process) + { + ptr.active = false; + } + } + dirty = true; } void JackClient::activate() @@ -111,10 +115,30 @@ void JackClient::activate() int JackClient::process(jack_nframes_t num_frames) { + // Clear out any inactive processes before iterating + if(dirty) + { + auto it = processes.begin(); + while(it != processes.end()) + { + if(it->active == false) + { + it = processes.erase(it); + } + else + { + it++; + } + } + + dirty = false; + } + for(auto& ptr : processes) { - ptr->process(num_frames); + ptr.process->process(num_frames); } + return 0; } @@ -122,7 +146,7 @@ void JackClient::jackLatencyCallback(jack_latency_callback_mode_t mode) { for(auto& ptr : processes) { - ptr->jackLatencyCallback(mode); + ptr.process->jackLatencyCallback(mode); } } diff --git a/drumgizmo/jackclient.h b/drumgizmo/jackclient.h index f769ab4..04d6654 100644 --- a/drumgizmo/jackclient.h +++ b/drumgizmo/jackclient.h @@ -27,7 +27,7 @@ #pragma once #include #include -#include +#include #include @@ -38,7 +38,7 @@ class JackClient; class JackProcess { public: - virtual ~JackProcess(); + virtual ~JackProcess() = default; virtual void process(jack_nframes_t num_frames) = 0; virtual void jackLatencyCallback(jack_latency_callback_mode_t mode) {} }; @@ -76,7 +76,13 @@ public: private: jack_client_t* client; - std::set processes; + bool dirty{false}; + struct JackProcessContainer + { + JackProcess *process; + bool active{true}; + }; + std::list processes; bool is_active; bool is_freewheeling; -- cgit v1.2.3