summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2022-01-22 20:42:50 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2022-01-22 22:21:44 +0100
commit235ad6fbbce2e0ae9e06db960a5ba3b099936ace (patch)
tree262344b30ef79237d157835ad9fcca4464bef1bc
parentd3c643565f6c7ad2824e4896ff8eaea25b95b460 (diff)
Prevent processing jack clients that are being deleted.
-rw-r--r--drumgizmo/jackclient.cc48
-rw-r--r--drumgizmo/jackclient.h12
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<JackClient*>(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<JackClient*>(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 <vector>
#include <string>
-#include <set>
+#include <list>
#include <jack/jack.h>
@@ -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<JackProcess*> processes;
+ bool dirty{false};
+ struct JackProcessContainer
+ {
+ JackProcess *process;
+ bool active{true};
+ };
+ std::list<JackProcessContainer> processes;
bool is_active;
bool is_freewheeling;