THREAD_CLEAN_PART2: Assure correct terminate()/isTerminated(delay)/delete sequence +

Removed the NotifyQueue between DemodulatorInstance participants, actually not needed
since DemodulatorInstance::IsTerminated() is explicitly called on some events for cleanups

DELETE_CLEANUP: properly nullify deleted pointers when needed
This commit is contained in:
vsonnier 2016-07-03 09:47:28 +02:00
parent cf90a829b0
commit 567d84711f
16 changed files with 163 additions and 154 deletions

View File

@ -293,43 +293,63 @@ int CubicSDR::OnExit() {
demodMgr.terminateAll(); demodMgr.terminateAll();
std::cout << "Terminating SDR thread.." << std::endl; std::cout << "Terminating SDR thread.." << std::endl;
if (!sdrThread->isTerminated()) { sdrThread->terminate();
sdrThread->terminate(); sdrThread->isTerminated(1000);
if (t_SDR) {
t_SDR->join(); if (t_SDR) {
} t_SDR->join();
} }
std::cout << "Terminating SDR post-processing thread.." << std::endl; std::cout << "Terminating SDR post-processing thread.." << std::endl;
sdrPostThread->terminate(); sdrPostThread->terminate();
t_PostSDR->join();
std::cout << "Terminating Visual Processor threads.." << std::endl; std::cout << "Terminating Visual Processor threads.." << std::endl;
spectrumVisualThread->terminate(); spectrumVisualThread->terminate();
t_SpectrumVisual->join();
demodVisualThread->terminate(); demodVisualThread->terminate();
t_DemodVisual->join();
//Poor man join //Wait nicely
sdrPostThread->isTerminated(1000); sdrPostThread->isTerminated(1000);
spectrumVisualThread->isTerminated(1000); spectrumVisualThread->isTerminated(1000);
demodVisualThread->isTerminated(1000); demodVisualThread->isTerminated(1000);
//Then join the thread themselves
t_PostSDR->join();
t_DemodVisual->join();
t_SpectrumVisual->join();
//Now only we can delete
delete sdrThread; delete sdrThread;
sdrThread = nullptr;
delete sdrPostThread; delete sdrPostThread;
sdrPostThread = nullptr;
delete t_PostSDR; delete t_PostSDR;
t_PostSDR = nullptr;
delete t_SpectrumVisual; delete t_SpectrumVisual;
t_SpectrumVisual = nullptr;
delete spectrumVisualThread; delete spectrumVisualThread;
spectrumVisualThread = nullptr;
delete t_DemodVisual; delete t_DemodVisual;
t_DemodVisual = nullptr;
delete demodVisualThread; delete demodVisualThread;
demodVisualThread = nullptr;
delete pipeIQVisualData; delete pipeIQVisualData;
pipeIQVisualData = nullptr;
delete pipeAudioVisualData; delete pipeAudioVisualData;
pipeAudioVisualData = nullptr;
delete pipeSDRIQData; delete pipeSDRIQData;
pipeSDRIQData = nullptr;
delete m_glContext; delete m_glContext;
m_glContext = nullptr;
#ifdef __APPLE__ #ifdef __APPLE__
AudioThread::deviceCleanup(); AudioThread::deviceCleanup();
@ -427,6 +447,7 @@ void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string mess
if (state == SDRThread::SDR_THREAD_TERMINATED) { if (state == SDRThread::SDR_THREAD_TERMINATED) {
t_SDR->join(); t_SDR->join();
delete t_SDR; delete t_SDR;
t_SDR = nullptr;
} }
if (state == SDRThread::SDR_THREAD_FAILED) { if (state == SDRThread::SDR_THREAD_FAILED) {
notifyMessage = message; notifyMessage = message;
@ -532,14 +553,15 @@ void CubicSDR::stopDevice(bool store) {
} }
sdrThread->setDevice(nullptr); sdrThread->setDevice(nullptr);
if (!sdrThread->isTerminated()) { sdrThread->terminate();
sdrThread->terminate(); sdrThread->isTerminated(1000);
if (t_SDR) {
t_SDR->join(); if (t_SDR) {
delete t_SDR; t_SDR->join();
t_SDR = nullptr; delete t_SDR;
} t_SDR = nullptr;
} }
} }
void CubicSDR::reEnumerateDevices() { void CubicSDR::reEnumerateDevices() {
@ -550,12 +572,14 @@ void CubicSDR::reEnumerateDevices() {
} }
void CubicSDR::setDevice(SDRDeviceInfo *dev) { void CubicSDR::setDevice(SDRDeviceInfo *dev) {
if (!sdrThread->isTerminated()) {
sdrThread->terminate(); sdrThread->terminate();
if (t_SDR) { sdrThread->isTerminated(1000);
t_SDR->join();
delete t_SDR; if (t_SDR) {
} t_SDR->join();
delete t_SDR;
t_SDR = nullptr;
} }
for (SoapySDR::Kwargs::const_iterator i = settingArgs.begin(); i != settingArgs.end(); i++) { for (SoapySDR::Kwargs::const_iterator i = settingArgs.begin(); i != settingArgs.end(); i++) {
@ -872,17 +896,27 @@ RigThread *CubicSDR::getRigThread() {
void CubicSDR::initRig(int rigModel, std::string rigPort, int rigSerialRate) { void CubicSDR::initRig(int rigModel, std::string rigPort, int rigSerialRate) {
if (rigThread) { if (rigThread) {
if (!rigThread->isTerminated()) {
rigThread->terminate(); rigThread->terminate();
} rigThread->isTerminated(1000);
}
if (t_Rig && t_Rig->joinable()) {
t_Rig->join();
}
//now we can delete
if (rigThread) {
delete rigThread; delete rigThread;
rigThread = nullptr; rigThread = nullptr;
} }
if (t_Rig && t_Rig->joinable()) { if (t_Rig) {
t_Rig->join();
delete t_Rig; delete t_Rig;
t_Rig = nullptr; t_Rig = nullptr;
} }
rigThread = new RigThread(); rigThread = new RigThread();
rigThread->initRig(rigModel, rigPort, rigSerialRate); rigThread->initRig(rigModel, rigPort, rigSerialRate);
rigThread->setControlMode(wxGetApp().getConfig()->getRigControlMode()); rigThread->setControlMode(wxGetApp().getConfig()->getRigControlMode());
@ -899,14 +933,24 @@ void CubicSDR::stopRig() {
} }
if (rigThread) { if (rigThread) {
if (!rigThread->isTerminated()) {
rigThread->terminate(); rigThread->terminate();
} rigThread->isTerminated(1000);
}
if (t_Rig && t_Rig->joinable()) {
t_Rig->join();
}
//now we can delete
if (rigThread) {
delete rigThread; delete rigThread;
rigThread = nullptr; rigThread = nullptr;
} }
if (t_Rig && t_Rig->joinable()) {
t_Rig->join(); if (t_Rig) {
delete t_Rig; delete t_Rig;
t_Rig = nullptr; t_Rig = nullptr;
} }

View File

@ -180,10 +180,10 @@ private:
DemodulatorMgr demodMgr; DemodulatorMgr demodMgr;
long long frequency; std::atomic_llong frequency;
long long offset; std::atomic_llong offset;
int ppm, snap; std::atomic_int ppm, snap;
long long sampleRate; std::atomic_llong sampleRate;
std::atomic_bool agcMode; std::atomic_bool agcMode;
SDRThread *sdrThread; SDRThread *sdrThread;
@ -224,7 +224,7 @@ private:
std::atomic_bool soloMode; std::atomic_bool soloMode;
SDRDeviceInfo *stoppedDev; SDRDeviceInfo *stoppedDev;
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
RigThread *rigThread; RigThread* rigThread;
std::thread *t_Rig; std::thread *t_Rig;
#endif #endif
}; };

View File

@ -1,4 +1,5 @@
#include "IOThread.h" #include "IOThread.h"
#include <typeinfo>
std::mutex ReBufferGC::g_mutex; std::mutex ReBufferGC::g_mutex;
std::set<ReferenceCounter *> ReBufferGC::garbage; std::set<ReferenceCounter *> ReBufferGC::garbage;
@ -122,5 +123,7 @@ bool IOThread::isTerminated(int waitMs) {
} }
} }
std::cout << "ERROR: thread '" << typeid(*this).name() << "' has not terminated in time ! (> " << waitMs << " ms)" << std::endl;
return terminated.load(); return terminated.load();
} }

View File

@ -12,7 +12,7 @@ std::map<int, int> AudioThread::deviceSampleRate;
std::map<int, std::thread *> AudioThread::deviceThread; std::map<int, std::thread *> AudioThread::deviceThread;
AudioThread::AudioThread() : IOThread(), AudioThread::AudioThread() : IOThread(),
currentInput(NULL), inputQueue(NULL), nBufferFrames(1024), threadQueueNotify(NULL), sampleRate(0) { currentInput(NULL), inputQueue(NULL), nBufferFrames(1024), sampleRate(0) {
audioQueuePtr.store(0); audioQueuePtr.store(0);
underflowCount.store(0); underflowCount.store(0);
@ -378,7 +378,6 @@ void AudioThread::run() {
// std::cout << "Audio thread started." << std::endl; // std::cout << "Audio thread started." << std::endl;
inputQueue = static_cast<AudioThreadInputQueue *>(getInputQueue("AudioDataInput")); inputQueue = static_cast<AudioThreadInputQueue *>(getInputQueue("AudioDataInput"));
threadQueueNotify = static_cast<DemodulatorThreadCommandQueue*>(getOutputQueue("NotifyQueue"));
while (!stopping) { while (!stopping) {
AudioThreadCommand command; AudioThreadCommand command;
@ -420,12 +419,7 @@ void AudioThread::run() {
e.printMessage(); e.printMessage();
} }
} }
if (threadQueueNotify != NULL) {
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED);
tCmd.context = this;
threadQueueNotify->push(tCmd);
}
// std::cout << "Audio thread done." << std::endl; // std::cout << "Audio thread done." << std::endl;
} }

View File

@ -86,7 +86,6 @@ private:
RtAudio::StreamOptions opts; RtAudio::StreamOptions opts;
RtAudio::StreamParameters parameters; RtAudio::StreamParameters parameters;
AudioThreadCommandQueue cmdQueue; AudioThreadCommandQueue cmdQueue;
DemodulatorThreadCommandQueue* threadQueueNotify;
int sampleRate; int sampleRate;
public: public:

View File

@ -10,29 +10,7 @@
#include "IOThread.h" #include "IOThread.h"
class DemodulatorThread; class DemodulatorThread;
class DemodulatorThreadCommand {
public:
enum DemodulatorThreadCommandEnum {
DEMOD_THREAD_CMD_NULL,
DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED,
DEMOD_THREAD_CMD_DEMOD_TERMINATED,
DEMOD_THREAD_CMD_AUDIO_TERMINATED
};
DemodulatorThreadCommand() :
cmd(DEMOD_THREAD_CMD_NULL), context(NULL), llong_value(0) {
}
DemodulatorThreadCommand(DemodulatorThreadCommandEnum cmd) :
cmd(cmd), context(NULL), llong_value(0) {
}
DemodulatorThreadCommandEnum cmd;
void *context;
long long llong_value;
};
class DemodulatorThreadControlCommand { class DemodulatorThreadControlCommand {
public: public:
@ -120,5 +98,4 @@ public:
typedef ThreadQueue<DemodulatorThreadIQData *> DemodulatorThreadInputQueue; typedef ThreadQueue<DemodulatorThreadIQData *> DemodulatorThreadInputQueue;
typedef ThreadQueue<DemodulatorThreadPostIQData *> DemodulatorThreadPostInputQueue; typedef ThreadQueue<DemodulatorThreadPostIQData *> DemodulatorThreadPostInputQueue;
typedef ThreadQueue<DemodulatorThreadCommand> DemodulatorThreadCommandQueue;
typedef ThreadQueue<DemodulatorThreadControlCommand> DemodulatorThreadControlCommandQueue; typedef ThreadQueue<DemodulatorThreadControlCommand> DemodulatorThreadControlCommandQueue;

View File

@ -51,14 +51,12 @@ DemodulatorInstance::DemodulatorInstance() {
pipeIQInputData = new DemodulatorThreadInputQueue; pipeIQInputData = new DemodulatorThreadInputQueue;
pipeIQDemodData = new DemodulatorThreadPostInputQueue; pipeIQDemodData = new DemodulatorThreadPostInputQueue;
pipeDemodNotify = new DemodulatorThreadCommandQueue;
audioThread = new AudioThread(); audioThread = new AudioThread();
demodulatorPreThread = new DemodulatorPreThread(this); demodulatorPreThread = new DemodulatorPreThread(this);
demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData); demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData);
demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData); demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData);
demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
pipeAudioData = new AudioThreadInputQueue; pipeAudioData = new AudioThreadInputQueue;
threadQueueControl = new DemodulatorThreadControlCommandQueue; threadQueueControl = new DemodulatorThreadControlCommandQueue;
@ -66,11 +64,9 @@ DemodulatorInstance::DemodulatorInstance() {
demodulatorThread = new DemodulatorThread(this); demodulatorThread = new DemodulatorThread(this);
demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData); demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData);
demodulatorThread->setInputQueue("ControlQueue",threadQueueControl); demodulatorThread->setInputQueue("ControlQueue",threadQueueControl);
demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData); demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData);
audioThread->setInputQueue("AudioDataInput", pipeAudioData); audioThread->setInputQueue("AudioDataInput", pipeAudioData);
audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
} }
DemodulatorInstance::~DemodulatorInstance() { DemodulatorInstance::~DemodulatorInstance() {
@ -82,7 +78,6 @@ DemodulatorInstance::~DemodulatorInstance() {
delete demodulatorPreThread; delete demodulatorPreThread;
delete pipeIQInputData; delete pipeIQInputData;
delete pipeIQDemodData; delete pipeIQDemodData;
delete pipeDemodNotify;
delete threadQueueControl; delete threadQueueControl;
delete pipeAudioData; delete pipeAudioData;
} }
@ -151,56 +146,59 @@ void DemodulatorInstance::setLabel(std::string labelStr) {
} }
bool DemodulatorInstance::isTerminated() { bool DemodulatorInstance::isTerminated() {
while (!pipeDemodNotify->empty()) {
DemodulatorThreadCommand cmd;
pipeDemodNotify->pop(cmd);
switch (cmd.cmd) {
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED:
if (t_Audio) {
t_Audio->join();
delete t_Audio;
t_Audio = nullptr;
}
break;
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED:
if (t_Demod) {
#ifdef __APPLE__
pthread_join(t_Demod, nullptr);
#else
t_Demod->join();
delete t_Demod;
#endif
t_Demod = nullptr;
}
#if ENABLE_DIGITAL_LAB
if (activeOutput) {
closeOutput();
}
#endif
break;
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED:
if (t_PreDemod) {
#ifdef __APPLE__
pthread_join(t_PreDemod, NULL);
#else
t_PreDemod->join();
delete t_PreDemod;
#endif
t_PreDemod = nullptr;
}
break;
default:
break;
}
}
// //
bool audioTerminated = audioThread->isTerminated(); bool audioTerminated = audioThread->isTerminated();
bool demodTerminated = demodulatorThread->isTerminated(); bool demodTerminated = demodulatorThread->isTerminated();
bool preDemodTerminated = demodulatorPreThread->isTerminated(); bool preDemodTerminated = demodulatorPreThread->isTerminated();
//Cleanup the worker threads, if the threads are indeed terminated
if (audioTerminated) {
if (t_Audio) {
t_Audio->join();
delete t_Audio;
t_Audio = nullptr;
}
}
if (demodTerminated) {
if (t_Demod) {
#ifdef __APPLE__
pthread_join(t_Demod, nullptr);
#else
t_Demod->join();
delete t_Demod;
#endif
t_Demod = nullptr;
}
#if ENABLE_DIGITAL_LAB
if (activeOutput) {
closeOutput();
}
#endif
}
if (preDemodTerminated) {
if (t_PreDemod) {
#ifdef __APPLE__
pthread_join(t_PreDemod, NULL);
#else
t_PreDemod->join();
delete t_PreDemod;
#endif
t_PreDemod = nullptr;
}
}
bool terminated = audioTerminated && demodTerminated && preDemodTerminated; bool terminated = audioTerminated && demodTerminated && preDemodTerminated;
return terminated; return terminated;

View File

@ -47,8 +47,6 @@ public:
void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue); void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue);
DemodulatorThreadCommandQueue *getCommandQueue();
void run(); void run();
void terminate(); void terminate();
std::string getLabel(); std::string getLabel();
@ -131,7 +129,6 @@ protected:
DemodulatorThreadInputQueue* pipeIQInputData; DemodulatorThreadInputQueue* pipeIQInputData;
DemodulatorThreadPostInputQueue* pipeIQDemodData; DemodulatorThreadPostInputQueue* pipeIQDemodData;
AudioThreadInputQueue *pipeAudioData; AudioThreadInputQueue *pipeAudioData;
DemodulatorThreadCommandQueue* pipeDemodNotify;
DemodulatorPreThread *demodulatorPreThread; DemodulatorPreThread *demodulatorPreThread;
DemodulatorThread *demodulatorThread; DemodulatorThread *demodulatorThread;
DemodulatorThreadControlCommandQueue *threadQueueControl; DemodulatorThreadControlCommandQueue *threadQueueControl;

View File

@ -148,14 +148,18 @@ void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
if (i != demods.end()) { if (i != demods.end()) {
demods.erase(i); demods.erase(i);
} }
//Ask for termination
demod->terminate(); demod->terminate();
//Do not cleanup immediatly
demods_deleted.push_back(demod); demods_deleted.push_back(demod);
} }
std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) { std::vector<DemodulatorInstance *> DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> *foundDemods = new std::vector<DemodulatorInstance *>();
std::vector<DemodulatorInstance *> foundDemods;
for (int i = 0, iMax = demods.size(); i < iMax; i++) { for (int i = 0, iMax = demods.size(); i < iMax; i++) {
DemodulatorInstance *testDemod = demods[i]; DemodulatorInstance *testDemod = demods[i];
@ -167,7 +171,7 @@ std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long
long long halfBuffer = bandwidth / 2; long long halfBuffer = bandwidth / 2;
if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != "LSB")?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != "USB")?halfBandwidthTest:0) - halfBuffer))) { if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != "LSB")?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != "USB")?halfBandwidthTest:0) - halfBuffer))) {
foundDemods->push_back(testDemod); foundDemods.push_back(testDemod);
} }
} }

View File

@ -14,7 +14,7 @@ public:
DemodulatorInstance *newThread(); DemodulatorInstance *newThread();
std::vector<DemodulatorInstance *> &getDemodulators(); std::vector<DemodulatorInstance *> &getDemodulators();
std::vector<DemodulatorInstance *> getOrderedDemodulators(bool actives = true); std::vector<DemodulatorInstance *> getOrderedDemodulators(bool actives = true);
std::vector<DemodulatorInstance *> *getDemodulatorsAt(long long freq, int bandwidth); std::vector<DemodulatorInstance *> getDemodulatorsAt(long long freq, int bandwidth);
DemodulatorInstance *getPreviousDemodulator(DemodulatorInstance *demod, bool actives = true); DemodulatorInstance *getPreviousDemodulator(DemodulatorInstance *demod, bool actives = true);
DemodulatorInstance *getNextDemodulator(DemodulatorInstance *demod, bool actives = true); DemodulatorInstance *getNextDemodulator(DemodulatorInstance *demod, bool actives = true);
DemodulatorInstance *getLastDemodulator(); DemodulatorInstance *getLastDemodulator();

View File

@ -9,7 +9,7 @@
#include "CubicSDR.h" #include "CubicSDR.h"
#include "DemodulatorInstance.h" #include "DemodulatorInstance.h"
DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL) DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL)
{ {
initialized.store(false); initialized.store(false);
this->parent = parent; this->parent = parent;
@ -58,7 +58,6 @@ void DemodulatorPreThread::run() {
iqInputQueue = static_cast<DemodulatorThreadInputQueue*>(getInputQueue("IQDataInput")); iqInputQueue = static_cast<DemodulatorThreadInputQueue*>(getInputQueue("IQDataInput"));
iqOutputQueue = static_cast<DemodulatorThreadPostInputQueue*>(getOutputQueue("IQDataOutput")); iqOutputQueue = static_cast<DemodulatorThreadPostInputQueue*>(getOutputQueue("IQDataOutput"));
threadQueueNotify = static_cast<DemodulatorThreadCommandQueue*>(getOutputQueue("NotifyQueue"));
std::vector<liquid_float_complex> in_buf_data; std::vector<liquid_float_complex> in_buf_data;
std::vector<liquid_float_complex> out_buf_data; std::vector<liquid_float_complex> out_buf_data;
@ -276,11 +275,6 @@ void DemodulatorPreThread::run() {
tmp->decRefCount(); tmp->decRefCount();
} }
buffers.purge(); buffers.purge();
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED);
tCmd.context = this;
threadQueueNotify->push(tCmd);
// std::cout << "Demodulator preprocessor thread done." << std::endl;
} }
void DemodulatorPreThread::setDemodType(std::string demodType) { void DemodulatorPreThread::setDemodType(std::string demodType) {
@ -346,12 +340,22 @@ void DemodulatorPreThread::terminate() {
iqInputQueue->push(inp); iqInputQueue->push(inp);
DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_NULL); DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_NULL);
workerQueue->push(command); workerQueue->push(command);
workerThread->terminate(); workerThread->terminate();
workerThread->isTerminated(1000);
t_Worker->join(); t_Worker->join();
delete t_Worker; delete t_Worker;
t_Worker = nullptr;
delete workerThread; delete workerThread;
workerThread = nullptr;
delete workerResults; delete workerResults;
workerResults = nullptr;
delete workerQueue; delete workerQueue;
workerQueue = nullptr;
} }
Modem *DemodulatorPreThread::getModem() { Modem *DemodulatorPreThread::getModem() {

View File

@ -79,5 +79,4 @@ protected:
DemodulatorThreadInputQueue* iqInputQueue; DemodulatorThreadInputQueue* iqInputQueue;
DemodulatorThreadPostInputQueue* iqOutputQueue; DemodulatorThreadPostInputQueue* iqOutputQueue;
DemodulatorThreadCommandQueue* threadQueueNotify;
}; };

View File

@ -69,8 +69,7 @@ void DemodulatorThread::run() {
iqInputQueue = static_cast<DemodulatorThreadPostInputQueue*>(getInputQueue("IQDataInput")); iqInputQueue = static_cast<DemodulatorThreadPostInputQueue*>(getInputQueue("IQDataInput"));
audioOutputQueue = static_cast<AudioThreadInputQueue*>(getOutputQueue("AudioDataOutput")); audioOutputQueue = static_cast<AudioThreadInputQueue*>(getOutputQueue("AudioDataOutput"));
threadQueueControl = static_cast<DemodulatorThreadControlCommandQueue *>(getInputQueue("ControlQueue")); threadQueueControl = static_cast<DemodulatorThreadControlCommandQueue *>(getInputQueue("ControlQueue"));
threadQueueNotify = static_cast<DemodulatorThreadCommandQueue*>(getOutputQueue("NotifyQueue"));
ModemIQData modemData; ModemIQData modemData;
while (!stopping) { while (!stopping) {
@ -290,13 +289,6 @@ void DemodulatorThread::run() {
} }
outputBuffers.purge(); outputBuffers.purge();
//Guard the cleanup of audioVisOutputQueue properly.
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED);
tCmd.context = this;
threadQueueNotify->push(tCmd);
// std::cout << "Demodulator thread done." << std::endl; // std::cout << "Demodulator thread done." << std::endl;
} }

View File

@ -56,7 +56,6 @@ protected:
AudioThreadInputQueue *audioOutputQueue = nullptr; AudioThreadInputQueue *audioOutputQueue = nullptr;
DemodulatorThreadOutputQueue* audioVisOutputQueue = nullptr; DemodulatorThreadOutputQueue* audioVisOutputQueue = nullptr;
DemodulatorThreadControlCommandQueue *threadQueueControl = nullptr; DemodulatorThreadControlCommandQueue *threadQueueControl = nullptr;
DemodulatorThreadCommandQueue* threadQueueNotify = nullptr;
//protects the audioVisOutputQueue dynamic binding change at runtime (in DemodulatorMgr) //protects the audioVisOutputQueue dynamic binding change at runtime (in DemodulatorMgr)
mutable std::mutex m_mutexAudioVisOutputQueue; mutable std::mutex m_mutexAudioVisOutputQueue;

View File

@ -400,7 +400,6 @@ void GLFont::loadFontOnce() {
} }
//2) then load from memory //2) then load from memory
lodepng::State state;
unsigned error = lodepng::decode(image, imgWidth, imgHeight, raw_image, png_size); unsigned error = lodepng::decode(image, imgWidth, imgHeight, raw_image, png_size);
delete[] raw_image; delete[] raw_image;

View File

@ -492,7 +492,7 @@ void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
void WaterfallCanvas::updateHoverState() { void WaterfallCanvas::updateHoverState() {
long long freqPos = getFrequencyAt(mouseTracker.getMouseX()); long long freqPos = getFrequencyAt(mouseTracker.getMouseX());
std::vector<DemodulatorInstance *> *demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000); std::vector<DemodulatorInstance *> demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000);
wxGetApp().getDemodMgr().setActiveDemodulator(NULL); wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
@ -505,13 +505,13 @@ void WaterfallCanvas::updateHoverState() {
} else { } else {
setStatusText("Click and drag to set the current demodulator range."); setStatusText("Click and drag to set the current demodulator range.");
} }
} else if (demodsHover->size() && !shiftDown) { } else if (demodsHover.size() && !shiftDown) {
long near_dist = getBandwidth(); long near_dist = getBandwidth();
DemodulatorInstance *activeDemodulator = NULL; DemodulatorInstance *activeDemodulator = NULL;
for (int i = 0, iMax = demodsHover->size(); i < iMax; i++) { for (int i = 0, iMax = demodsHover.size(); i < iMax; i++) {
DemodulatorInstance *demod = (*demodsHover)[i]; DemodulatorInstance *demod = demodsHover[i];
long long freqDiff = demod->getFrequency() - freqPos; long long freqDiff = demod->getFrequency() - freqPos;
long halfBw = (demod->getBandwidth() / 2); long halfBw = (demod->getBandwidth() / 2);
long long currentBw = getBandwidth(); long long currentBw = getBandwidth();
@ -574,18 +574,18 @@ void WaterfallCanvas::updateHoverState() {
mouseTracker.setHorizDragLock(false); mouseTracker.setHorizDragLock(false);
setStatusText("Click and drag to change demodulator frequency; SPACE or numeric key for direct input. [, ] to nudge, M for mute, D to delete, C to center, E to edit label."); setStatusText("Click and drag to change demodulator frequency; SPACE or numeric key for direct input. [, ] to nudge, M for mute, D to delete, C to center, E to edit label.");
} }
} else { }
else {
SetCursor(wxCURSOR_CROSS); SetCursor(wxCURSOR_CROSS);
nextDragState = WF_DRAG_NONE; nextDragState = WF_DRAG_NONE;
if (shiftDown) { if (shiftDown) {
setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE or numeric key for direct center frequency input."); setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE or numeric key for direct center frequency input.");
} else { }
else {
setStatusText( setStatusText(
"Click to set active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or wheel to Zoom. Arrow keys to navigate/zoom, C to center."); "Click to set active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or wheel to Zoom. Arrow keys to navigate/zoom, C to center.");
} }
} }
delete demodsHover;
} }
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {