From 9f65a6e636b2923101155c6b368f416a393e6fb2 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 22 Sep 2022 10:54:15 +0200 Subject: [PATCH] Update threading model in Simple PTT feature. Part of #1346 --- plugins/feature/simpleptt/simpleptt.cpp | 83 ++++++++++++++----- plugins/feature/simpleptt/simpleptt.h | 7 +- plugins/feature/simpleptt/simplepttworker.cpp | 6 +- plugins/feature/simpleptt/simplepttworker.h | 4 +- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/plugins/feature/simpleptt/simpleptt.cpp b/plugins/feature/simpleptt/simpleptt.cpp index e08f8b111..fafaf8598 100644 --- a/plugins/feature/simpleptt/simpleptt.cpp +++ b/plugins/feature/simpleptt/simpleptt.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "SWGFeatureSettings.h" #include "SWGFeatureReport.h" @@ -41,12 +42,12 @@ const char* const SimplePTT::m_featureId = "SimplePTT"; SimplePTT::SimplePTT(WebAPIAdapterInterface *webAPIAdapterInterface) : Feature(m_featureIdURI, webAPIAdapterInterface), + m_thread(nullptr), + m_running(false), + m_worker(nullptr), m_ptt(false) { setObjectName(m_featureId); - m_worker = new SimplePTTWorker(webAPIAdapterInterface); - m_worker->moveToThread(&m_thread); - m_state = StIdle; m_errorMessage = "SimplePTT error"; m_networkManager = new QNetworkAccessManager(); QObject::connect( @@ -66,34 +67,66 @@ SimplePTT::~SimplePTT() &SimplePTT::networkManagerFinished ); delete m_networkManager; - if (m_worker->isRunning()) { - stop(); - } - - delete m_worker; + stop(); } void SimplePTT::start() { - qDebug("SimplePTT::start"); + QMutexLocker m_lock(&m_mutex); + + if (m_running) { + return; + } + + qDebug("SimplePTT::start"); + m_thread = new QThread(); + m_worker = new SimplePTTWorker(getWebAPIAdapterInterface()); + m_worker->moveToThread(m_thread); + + QObject::connect( + m_thread, + &QThread::started, + m_worker, + &SimplePTTWorker::startWork + ); + QObject::connect( + m_thread, + &QThread::finished, + m_worker, + &QObject::deleteLater + ); + QObject::connect( + m_thread, + &QThread::finished, + m_thread, + &QThread::deleteLater + ); - m_worker->reset(); m_worker->setMessageQueueToGUI(getMessageQueueToGUI()); - bool ok = m_worker->startWork(); - m_state = ok ? StRunning : StError; - m_thread.start(); + m_worker->startWork(); + m_state = StRunning; + m_thread->start(); SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create(m_settings, true); m_worker->getInputMessageQueue()->push(msg); + + m_running = true; } void SimplePTT::stop() { + QMutexLocker m_lock(&m_mutex); + + if (!m_running) { + return; + } + qDebug("SimplePTT::stop"); + m_running = false; m_worker->stopWork(); m_state = StIdle; - m_thread.quit(); - m_thread.wait(); + m_thread->quit(); + m_thread->wait(); } bool SimplePTT::handleMessage(const Message& cmd) @@ -112,8 +145,11 @@ bool SimplePTT::handleMessage(const Message& cmd) m_ptt = cfg.getTx(); qDebug() << "SimplePTT::handleMessage: MsgPTT: tx:" << m_ptt; - SimplePTTWorker::MsgPTT *msg = SimplePTTWorker::MsgPTT::create(m_ptt); - m_worker->getInputMessageQueue()->push(msg); + if (m_running) + { + SimplePTTWorker::MsgPTT *msg = SimplePTTWorker::MsgPTT::create(m_ptt); + m_worker->getInputMessageQueue()->push(msg); + } return true; } @@ -160,7 +196,7 @@ bool SimplePTT::deserialize(const QByteArray& data) void SimplePTT::getAudioPeak(float& peak) { - if (m_worker) { + if (m_running) { m_worker->getAudioPeak(peak); } } @@ -214,10 +250,13 @@ void SimplePTT::applySettings(const SimplePTTSettings& settings, bool force) reverseAPIKeys.append("voxLevel"); } - SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create( - settings, force - ); - m_worker->getInputMessageQueue()->push(msg); + if (m_running) + { + SimplePTTWorker::MsgConfigureSimplePTTWorker *msg = SimplePTTWorker::MsgConfigureSimplePTTWorker::create( + settings, force + ); + m_worker->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { diff --git a/plugins/feature/simpleptt/simpleptt.h b/plugins/feature/simpleptt/simpleptt.h index 182b53f9e..223d7d32a 100644 --- a/plugins/feature/simpleptt/simpleptt.h +++ b/plugins/feature/simpleptt/simpleptt.h @@ -18,7 +18,7 @@ #ifndef INCLUDE_FEATURE_SIMPLEPTT_H_ #define INCLUDE_FEATURE_SIMPLEPTT_H_ -#include +#include #include #include "feature/feature.h" @@ -30,6 +30,7 @@ class WebAPIAdapterInterface; class SimplePTTWorker; class QNetworkAccessManager; class QNetworkReply; +class QThread; namespace SWGSDRangel { class SWGDeviceState; @@ -149,7 +150,9 @@ public: static const char* const m_featureId; private: - QThread m_thread; + QThread *m_thread; + QRecursiveMutex m_mutex; + bool m_running; SimplePTTWorker *m_worker; SimplePTTSettings m_settings; bool m_ptt; diff --git a/plugins/feature/simpleptt/simplepttworker.cpp b/plugins/feature/simpleptt/simplepttworker.cpp index ef735cc2f..f811a5ff8 100644 --- a/plugins/feature/simpleptt/simplepttworker.cpp +++ b/plugins/feature/simpleptt/simplepttworker.cpp @@ -35,7 +35,6 @@ MESSAGE_CLASS_DEFINITION(SimplePTTWorker::MsgPTT, Message) SimplePTTWorker::SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : m_webAPIAdapterInterface(webAPIAdapterInterface), m_msgQueueToGUI(nullptr), - m_running(false), m_tx(false), m_audioFifo(12000), m_audioSampleRate(48000), @@ -63,19 +62,16 @@ void SimplePTTWorker::reset() m_inputMessageQueue.clear(); } -bool SimplePTTWorker::startWork() +void SimplePTTWorker::startWork() { QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_running = true; - return m_running; } void SimplePTTWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_running = false; } void SimplePTTWorker::handleInputMessages() diff --git a/plugins/feature/simpleptt/simplepttworker.h b/plugins/feature/simpleptt/simplepttworker.h index f51b55cd2..6ef325c09 100644 --- a/plugins/feature/simpleptt/simplepttworker.h +++ b/plugins/feature/simpleptt/simplepttworker.h @@ -78,9 +78,8 @@ public: SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface); ~SimplePTTWorker(); void reset(); - bool startWork(); + void startWork(); void stopWork(); - bool isRunning() const { return m_running; } MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } void setMessageQueueToGUI(MessageQueue *messageQueue) { m_msgQueueToGUI = messageQueue; } @@ -95,7 +94,6 @@ private: MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication MessageQueue *m_msgQueueToGUI; //!< Queue to report state to GUI SimplePTTSettings m_settings; - bool m_running; bool m_tx; AudioFifo m_audioFifo; AudioVector m_audioReadBuffer;