summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-03-25 18:21:12 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-03-25 18:21:12 +0100
commit887d270a8327da46a89d8e5375f172db778f0ff9 (patch)
tree449d2f0c39ea121490e013d9a9ab221ccdcdd5a2
parentf9e0a5c8eef355e14e276a7456ca020a11f24924 (diff)
downloaddabmod-887d270a8327da46a89d8e5375f172db778f0ff9.tar.gz
dabmod-887d270a8327da46a89d8e5375f172db778f0ff9.tar.bz2
dabmod-887d270a8327da46a89d8e5375f172db778f0ff9.zip
Fix race condition for PipelinedModCodec thread startup
The thread could start before the vtable containing the subclass function is ready, leading to a crash because the thread calls a pure virtual function.
-rw-r--r--src/FIRFilter.cpp2
-rw-r--r--src/FIRFilter.h2
-rw-r--r--src/GainControl.cpp2
-rw-r--r--src/ModPlugin.cpp10
-rw-r--r--src/ModPlugin.h9
5 files changed, 20 insertions, 5 deletions
diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp
index 0e85e0f..4296822 100644
--- a/src/FIRFilter.cpp
+++ b/src/FIRFilter.cpp
@@ -83,6 +83,8 @@ FIRFilter::FIRFilter(const std::string& taps_file) :
RC_ADD_PARAMETER(tapsfile, "Filename containing filter taps. When written to, the new file gets automatically loaded.");
load_filter_taps(m_taps_file);
+
+ start_pipeline_thread();
}
void FIRFilter::load_filter_taps(const std::string &tapsFile)
diff --git a/src/FIRFilter.h b/src/FIRFilter.h
index 1fe0004..fb6b4d6 100644
--- a/src/FIRFilter.h
+++ b/src/FIRFilter.h
@@ -65,7 +65,7 @@ public:
protected:
- int internal_process(Buffer* const dataIn, Buffer* dataOut);
+ virtual int internal_process(Buffer* const dataIn, Buffer* dataOut);
void load_filter_taps(const std::string &tapsFile);
std::string m_taps_file;
diff --git a/src/GainControl.cpp b/src/GainControl.cpp
index 9eb1678..f363d20 100644
--- a/src/GainControl.cpp
+++ b/src/GainControl.cpp
@@ -69,6 +69,8 @@ GainControl::GainControl(size_t framesize,
RC_ADD_PARAMETER(digital, "Digital Gain");
RC_ADD_PARAMETER(mode, "Gainmode (fix|max|var)");
RC_ADD_PARAMETER(var, "Variance setting for gainmode var (default: 4)");
+
+ start_pipeline_thread();
}
GainControl::~GainControl()
diff --git a/src/ModPlugin.cpp b/src/ModPlugin.cpp
index 34ad797..74db5f9 100644
--- a/src/ModPlugin.cpp
+++ b/src/ModPlugin.cpp
@@ -74,10 +74,11 @@ int ModOutput::process(
PipelinedModCodec::PipelinedModCodec() :
ModCodec(),
+ m_number_of_runs(0),
m_input_queue(),
m_output_queue(),
- m_number_of_runs(0),
- m_thread(&PipelinedModCodec::process_thread, this)
+ m_running(false),
+ m_thread()
{
}
@@ -89,6 +90,11 @@ PipelinedModCodec::~PipelinedModCodec()
}
}
+void PipelinedModCodec::start_pipeline_thread()
+{
+ m_thread = std::thread(&PipelinedModCodec::process_thread, this);
+}
+
int PipelinedModCodec::process(Buffer* dataIn, Buffer* dataOut)
{
if (!m_running) {
diff --git a/src/ModPlugin.h b/src/ModPlugin.h
index f3a8e2a..d3aa780 100644
--- a/src/ModPlugin.h
+++ b/src/ModPlugin.h
@@ -83,15 +83,20 @@ public:
virtual const char* name() = 0;
protected:
- void process_thread(void);
+ // Once the instance implementing PipelinedModCodec has been constructed,
+ // it must call start_pipeline_thread()
+ void start_pipeline_thread(void);
virtual int internal_process(Buffer* const dataIn, Buffer* dataOut) = 0;
+private:
+ size_t m_number_of_runs;
+
ThreadsafeQueue<std::shared_ptr<Buffer> > m_input_queue;
ThreadsafeQueue<std::shared_ptr<Buffer> > m_output_queue;
std::atomic<bool> m_running;
- size_t m_number_of_runs;
std::thread m_thread;
+ void process_thread(void);
};