From 95fcb307338e21d29e7410b8de7030c4f7d8c8b3 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Thu, 8 Jan 2015 21:12:49 -0500 Subject: [PATCH] Audio thread lock fix --- src/audio/AudioThread.cpp | 29 +++++++++++++++++++++++++++ src/audio/AudioThread.h | 1 + src/demod/DemodulatorInstance.cpp | 32 ++++++++++++++++++++++-------- src/demod/DemodulatorPreThread.cpp | 2 ++ src/demod/DemodulatorPreThread.h | 4 ++++ src/demod/DemodulatorThread.cpp | 2 ++ 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index be9ed92..ce07cbd 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -72,6 +72,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } srcmix->inputQueue->pop(srcmix->currentInput); + if (srcmix->terminated) { + continue; + } srcmix->audioQueuePtr = 0; continue; } @@ -88,6 +91,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } srcmix->inputQueue->pop(srcmix->currentInput); + if (srcmix->terminated) { + continue; + } srcmix->audioQueuePtr = 0; } continue; @@ -104,6 +110,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } srcmix->inputQueue->pop(srcmix->currentInput); + if (srcmix->terminated) { + continue; + } srcmix->audioQueuePtr = 0; } if (srcmix->currentInput && srcmix->currentInput->data.size()) { @@ -124,6 +133,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } srcmix->inputQueue->pop(srcmix->currentInput); + if (srcmix->terminated) { + continue; + } srcmix->audioQueuePtr = 0; } if (srcmix->currentInput && srcmix->currentInput->data.size()) { @@ -151,6 +163,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu if (!src->currentInput) { src->inputQueue->pop(src->currentInput); + if (src->terminated) { + return 1; + } src->audioQueuePtr = 0; return 0; } @@ -167,6 +182,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu return 1; } src->inputQueue->pop(src->currentInput); + if (src->terminated) { + return 1; + } src->audioQueuePtr = 0; } return 0; @@ -183,6 +201,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu return 1; } src->inputQueue->pop(src->currentInput); + if (src->terminated) { + return 1; + } src->audioQueuePtr = 0; } if (src->currentInput && src->currentInput->data.size()) { @@ -201,6 +222,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu return 1; } src->inputQueue->pop(src->currentInput); + if (src->terminated) { + return 1; + } src->audioQueuePtr = 0; } if (src->currentInput && src->currentInput->data.size()) { @@ -348,6 +372,8 @@ void AudioThread::threadMain() { std::cout << "Audio thread started." << std::endl; + terminated = false; + while (!terminated) { AudioThreadCommand command; cmdQueue.pop(command); @@ -357,6 +383,9 @@ void AudioThread::threadMain() { } } + AudioThreadInput dummy; + inputQueue->push(&dummy); + #ifdef __APPLE__ if (deviceController[parameters.deviceId] != this) { deviceController[parameters.deviceId]->removeThread(this); diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index d18b1e4..f849af7 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -60,6 +60,7 @@ public: std::atomic audioQueuePtr; std::atomic underflowCount; std::atomic terminated; + std::atomic initialized; std::atomic active; std::atomic outputDevice; float gain; diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 4b54ff9..72c1451 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -1,8 +1,8 @@ #include "DemodulatorInstance.h" DemodulatorInstance::DemodulatorInstance() : - t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(false), audioTerminated(false), demodTerminated( - false), preDemodTerminated(false), active(false), squelch(false), stereo(false), currentFrequency(0), currentBandwidth(0) { + t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(true), audioTerminated(true), demodTerminated( + true), preDemodTerminated(true), active(false), squelch(false), stereo(false), currentFrequency(0), currentBandwidth(0) { label = new std::string("Unnamed"); threadQueueDemod = new DemodulatorThreadInputQueue; @@ -26,9 +26,13 @@ DemodulatorInstance::DemodulatorInstance() : DemodulatorInstance::~DemodulatorInstance() { delete audioThread; delete demodulatorThread; - - delete audioInputQueue; + delete demodulatorPreThread; delete threadQueueDemod; + delete threadQueuePostDemod; + delete threadQueueCommand; + delete threadQueueNotify; + delete threadQueueControl; + delete audioInputQueue; } void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { @@ -36,7 +40,16 @@ void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQu } void DemodulatorInstance::run() { + if (active) { + return; + } + +// while (!isTerminated()) { +// std::this_thread::sleep_for(std::chrono::milliseconds(1)); +// } + currentFrequency = demodulatorPreThread->getParams().frequency; + currentDemodType = demodulatorThread->getDemodulatorType(); t_Audio = new std::thread(&AudioThread::threadMain, audioThread); @@ -63,6 +76,8 @@ void DemodulatorInstance::run() { t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread); #endif active = true; + audioTerminated = demodTerminated = preDemodTerminated = terminated = false; + } void DemodulatorInstance::updateLabel(long long freq) { @@ -109,12 +124,10 @@ bool DemodulatorInstance::isTerminated() { switch (cmd.cmd) { case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED: - audioThread = NULL; t_Audio->join(); audioTerminated = true; break; case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED: - demodulatorThread = NULL; #ifdef __APPLE__ pthread_join(t_Demod, NULL); #else @@ -123,7 +136,6 @@ bool DemodulatorInstance::isTerminated() { demodTerminated = true; break; case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED: - demodulatorPreThread = NULL; #ifdef __APPLE__ pthread_join(t_PreDemod, NULL); #else @@ -146,8 +158,12 @@ bool DemodulatorInstance::isActive() { } void DemodulatorInstance::setActive(bool state) { + if (active && !state) { + audioThread->setActive(state); + } else if (!active && state) { + audioThread->setActive(state); + } active = state; - audioThread->setActive(state); } bool DemodulatorInstance::isStereo() { diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 0b6d3d2..5dedd65 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -70,6 +70,8 @@ void DemodulatorPreThread::threadMain() { std::vector in_buf_data; std::vector out_buf_data; + terminated = false; + while (!terminated) { DemodulatorThreadIQData *inp; iqInputQueue->pop(inp); diff --git a/src/demod/DemodulatorPreThread.h b/src/demod/DemodulatorPreThread.h index 2785b2b..e5d8467 100644 --- a/src/demod/DemodulatorPreThread.h +++ b/src/demod/DemodulatorPreThread.h @@ -32,6 +32,10 @@ public: return params; } + void setParams(DemodulatorThreadParameters ¶ms_in) { + params = params_in; + } + void initialize(); void terminate(); diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index e67a7b8..bd13056 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -92,6 +92,8 @@ void DemodulatorThread::threadMain() { std::cout << "Demodulator thread started.." << std::endl; + terminated = false; + while (!terminated) { DemodulatorThreadPostIQData *inp; iqInputQueue->pop(inp);