diff --git a/plugins/feature/afc/afc.cpp b/plugins/feature/afc/afc.cpp index 0fa970b26..c4416cb15 100644 --- a/plugins/feature/afc/afc.cpp +++ b/plugins/feature/afc/afc.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "SWGFeatureSettings.h" #include "SWGFeatureReport.h" @@ -48,14 +49,15 @@ const char* const AFC::m_featureId = "AFC"; AFC::AFC(WebAPIAdapterInterface *webAPIAdapterInterface) : Feature(m_featureIdURI, webAPIAdapterInterface), + m_thread(nullptr), + m_mutex(QMutex::Recursive), + m_running(false), m_trackerDeviceSet(nullptr), m_trackedDeviceSet(nullptr), m_trackerIndexInDeviceSet(-1), m_trackerChannelAPI(nullptr) { setObjectName(m_featureId); - m_worker = new AFCWorker(webAPIAdapterInterface); - m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "AFC error"; m_networkManager = new QNetworkAccessManager(); @@ -76,36 +78,66 @@ AFC::~AFC() &AFC::networkManagerFinished ); delete m_networkManager; - if (m_worker->isRunning()) { - stop(); - } - - delete m_worker; + stop(); removeTrackerFeatureReference(); removeTrackedFeatureReferences(); } void AFC::start() { - qDebug("AFC::start"); + QMutexLocker m_lock(&m_mutex); + + if (m_running) { + return; + } + + qDebug("AFC::start"); + m_thread = new QThread(); + m_worker = new AFCWorker(getWebAPIAdapterInterface()); + m_worker->moveToThread(m_thread); + + QObject::connect( + m_thread, + &QThread::started, + m_worker, + &AFCWorker::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_thread->start(); AFCWorker::MsgConfigureAFCWorker *msg = AFCWorker::MsgConfigureAFCWorker::create(m_settings, true); m_worker->getInputMessageQueue()->push(msg); + + m_state = StRunning; + m_running = true; } void AFC::stop() { + QMutexLocker m_lock(&m_mutex); + + if (!m_running) { + return; + } + qDebug("AFC::stop"); - m_worker->stopWork(); + m_running = false; m_state = StIdle; - m_thread.quit(); - m_thread.wait(); + m_thread->quit(); + m_thread->wait(); } bool AFC::handleMessage(const Message& cmd) @@ -138,7 +170,7 @@ bool AFC::handleMessage(const Message& cmd) QString *channelType = swgChannelSettings->getChannelType(); qDebug() << "AFC::handleMessage: MainCore::MsgChannelSettings: " << *channelType; - if (m_worker->isRunning()) + if (m_running) { m_worker->getInputMessageQueue()->push(&cfg); } @@ -150,7 +182,7 @@ bool AFC::handleMessage(const Message& cmd) } else if (MsgDeviceTrack::match(cmd)) { - if (m_worker->isRunning()) + if (m_running) { AFCWorker::MsgDeviceTrack *msg = AFCWorker::MsgDeviceTrack::create(); m_worker->getInputMessageQueue()->push(msg); @@ -166,7 +198,7 @@ bool AFC::handleMessage(const Message& cmd) removeTrackedFeatureReferences(); trackedDeviceChange(m_settings.m_trackedDeviceSetIndex); - if (m_worker->isRunning()) + if (m_running) { AFCWorker::MsgDevicesApply *msg = AFCWorker::MsgDevicesApply::create(); m_worker->getInputMessageQueue()->push(msg); @@ -262,10 +294,13 @@ void AFC::applySettings(const AFCSettings& settings, bool force) trackedDeviceChange(settings.m_trackedDeviceSetIndex); } - AFCWorker::MsgConfigureAFCWorker *msg = AFCWorker::MsgConfigureAFCWorker::create( - settings, force - ); - m_worker->getInputMessageQueue()->push(msg); + if (m_running) + { + AFCWorker::MsgConfigureAFCWorker *msg = AFCWorker::MsgConfigureAFCWorker::create( + settings, force + ); + m_worker->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { @@ -536,9 +571,12 @@ void AFC::webapiUpdateFeatureSettings( void AFC::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response) { response.getAfcReport()->setTrackerChannelIndex(m_trackerIndexInDeviceSet); - response.getAfcReport()->setTrackerDeviceFrequency(m_worker->getTrackerDeviceFrequency()); - response.getAfcReport()->setTrackerChannelOffset(m_worker->getTrackerChannelOffset()); response.getAfcReport()->setRunningState(getState()); + + if (m_running) { + response.getAfcReport()->setTrackerDeviceFrequency(m_worker->getTrackerDeviceFrequency()); + response.getAfcReport()->setTrackerChannelOffset(m_worker->getTrackerChannelOffset()); + } } void AFC::webapiReverseSendSettings(QList& channelSettingsKeys, const AFCSettings& settings, bool force) diff --git a/plugins/feature/afc/afc.h b/plugins/feature/afc/afc.h index 767f874a5..4b141df84 100644 --- a/plugins/feature/afc/afc.h +++ b/plugins/feature/afc/afc.h @@ -18,8 +18,8 @@ #ifndef INCLUDE_FEATURE_AFC_H_ #define INCLUDE_FEATURE_AFC_H_ -#include #include +#include #include "feature/feature.h" #include "util/message.h" @@ -31,6 +31,7 @@ class QNetworkReply; class WebAPIAdapterInterface; class DeviceSet; class AFCWorker; +class QThread; namespace SWGSDRangel { class SWGDeviceState; @@ -201,7 +202,9 @@ public: static const char* const m_featureId; private: - QThread m_thread; + QThread *m_thread; + QMutex m_mutex; + bool m_running; AFCWorker *m_worker; AFCSettings m_settings; DeviceSet *m_trackerDeviceSet; diff --git a/plugins/feature/afc/afcworker.cpp b/plugins/feature/afc/afcworker.cpp index 53d78df5b..7274b4f09 100644 --- a/plugins/feature/afc/afcworker.cpp +++ b/plugins/feature/afc/afcworker.cpp @@ -42,7 +42,6 @@ MESSAGE_CLASS_DEFINITION(AFCWorker::MsgDevicesApply, Message) AFCWorker::AFCWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : m_webAPIAdapterInterface(webAPIAdapterInterface), m_msgQueueToGUI(nullptr), - m_running(false), m_freqTracker(nullptr), m_trackerDeviceFrequency(0), m_trackerChannelOffset(0), @@ -59,6 +58,7 @@ AFCWorker::AFCWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : AFCWorker::~AFCWorker() { m_inputMessageQueue.clear(); + stopWork(); } void AFCWorker::reset() @@ -67,19 +67,16 @@ void AFCWorker::reset() m_inputMessageQueue.clear(); } -bool AFCWorker::startWork() +void AFCWorker::startWork() { QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_running = true; - return m_running; } void AFCWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_running = false; } void AFCWorker::handleInputMessages() diff --git a/plugins/feature/afc/afcworker.h b/plugins/feature/afc/afcworker.h index 795b1b6a1..19b5b61ad 100644 --- a/plugins/feature/afc/afcworker.h +++ b/plugins/feature/afc/afcworker.h @@ -107,9 +107,8 @@ public: AFCWorker(WebAPIAdapterInterface *webAPIAdapterInterface); ~AFCWorker(); 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; } uint64_t getTrackerDeviceFrequency() const { return m_trackerDeviceFrequency; } @@ -145,7 +144,6 @@ private: MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication MessageQueue *m_msgQueueToGUI; //!< Queue to report state to GUI AFCSettings m_settings; - bool m_running; DeviceSet *m_trackerDeviceSet; DeviceSet *m_trackedDeviceSet; ChannelAPI *m_freqTracker; diff --git a/sdrbase/feature/feature.h b/sdrbase/feature/feature.h index 0529b3846..fa868ff68 100644 --- a/sdrbase/feature/feature.h +++ b/sdrbase/feature/feature.h @@ -152,6 +152,7 @@ public: MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } void setWorkspaceIndex(int index) { m_workspaceIndex = index; } int getWorkspaceIndex() const { return m_workspaceIndex; } + WebAPIAdapterInterface *getWebAPIAdapterInterface() { return m_webAPIAdapterInterface; } protected: MessageQueue m_inputMessageQueue;