diff --git a/plugins/feature/afc/afc.cpp b/plugins/feature/afc/afc.cpp index a8f647f55..2f49fbec9 100644 --- a/plugins/feature/afc/afc.cpp +++ b/plugins/feature/afc/afc.cpp @@ -52,6 +52,7 @@ AFC::AFC(WebAPIAdapterInterface *webAPIAdapterInterface) : { setObjectName(m_featureId); m_worker = new AFCWorker(webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "AFC error"; m_networkManager = new QNetworkAccessManager(); diff --git a/plugins/feature/afc/afcworker.cpp b/plugins/feature/afc/afcworker.cpp index 3b9de9e13..8f48c7536 100644 --- a/plugins/feature/afc/afcworker.cpp +++ b/plugins/feature/afc/afcworker.cpp @@ -46,6 +46,7 @@ AFCWorker::AFCWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : m_freqTracker(nullptr), m_trackerDeviceFrequency(0), m_trackerChannelOffset(0), + m_updateTimer(this), m_mutex(QMutex::Recursive) { qDebug("AFCWorker::AFCWorker"); diff --git a/plugins/feature/aprs/aprs.cpp b/plugins/feature/aprs/aprs.cpp index 29c315fa2..6074a87dc 100644 --- a/plugins/feature/aprs/aprs.cpp +++ b/plugins/feature/aprs/aprs.cpp @@ -46,6 +46,7 @@ APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) : qDebug("APRS::APRS: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new APRSWorker(this, webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "APRS error"; connect(&m_updatePipesTimer, SIGNAL(timeout()), this, SLOT(updatePipes())); diff --git a/plugins/feature/aprs/aprsworker.cpp b/plugins/feature/aprs/aprsworker.cpp index 2764daab2..09f8e3cab 100644 --- a/plugins/feature/aprs/aprsworker.cpp +++ b/plugins/feature/aprs/aprsworker.cpp @@ -38,7 +38,8 @@ APRSWorker::APRSWorker(APRS *aprs, WebAPIAdapterInterface *webAPIAdapterInterfac m_msgQueueToFeature(nullptr), m_msgQueueToGUI(nullptr), m_running(false), - m_mutex(QMutex::Recursive) + m_mutex(QMutex::Recursive), + m_socket(this) { connect(&m_socket, SIGNAL(readyRead()),this, SLOT(recv())); connect(&m_socket, SIGNAL(connected()), this, SLOT(connected())); @@ -65,18 +66,32 @@ bool APRSWorker::startWork() { QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + connect(thread(), SIGNAL(started()), this, SLOT(started())); + connect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = true; return m_running; } +// startWork() is called from main thread. Timers need to be started on worker thread +void APRSWorker::started() +{ + disconnect(thread(), SIGNAL(started()), this, SLOT(started())); +} + void APRSWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_running = false; +} + +void APRSWorker::finished() +{ // Close any existing connection - if (m_socket.isOpen()) + if (m_socket.isOpen()) { m_socket.close(); + } + m_running = false; + disconnect(thread(), SIGNAL(finished()), this, SLOT(finished())); } void APRSWorker::handleInputMessages() diff --git a/plugins/feature/aprs/aprsworker.h b/plugins/feature/aprs/aprsworker.h index 2c9c36dd1..225afa96f 100644 --- a/plugins/feature/aprs/aprsworker.h +++ b/plugins/feature/aprs/aprsworker.h @@ -20,7 +20,6 @@ #define INCLUDE_FEATURE_APRSWORKER_H_ #include -#include #include #include "util/message.h" @@ -87,6 +86,8 @@ private: void send(const char *data, int length); private slots: + void started(); + void finished(); void handleInputMessages(); void connected(); void disconnected(); diff --git a/plugins/feature/demodanalyzer/demodanalyzer.cpp b/plugins/feature/demodanalyzer/demodanalyzer.cpp index 39ba5a8aa..1fce21d84 100644 --- a/plugins/feature/demodanalyzer/demodanalyzer.cpp +++ b/plugins/feature/demodanalyzer/demodanalyzer.cpp @@ -55,6 +55,7 @@ DemodAnalyzer::DemodAnalyzer(WebAPIAdapterInterface *webAPIAdapterInterface) : qDebug("DemodAnalyzer::DemodAnalyzer: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new DemodAnalyzerWorker(); + m_worker->moveToThread(&m_thread); m_worker->setScopeVis(&m_scopeVis); m_state = StIdle; m_errorMessage = "DemodAnalyzer error"; diff --git a/plugins/feature/gs232controller/gs232controller.cpp b/plugins/feature/gs232controller/gs232controller.cpp index eb7c0128e..90ff4b315 100644 --- a/plugins/feature/gs232controller/gs232controller.cpp +++ b/plugins/feature/gs232controller/gs232controller.cpp @@ -52,6 +52,7 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface) qDebug("GS232Controller::GS232Controller: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new GS232ControllerWorker(); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "GS232Controller error"; m_selectedPipe = nullptr; diff --git a/plugins/feature/gs232controller/gs232controllerworker.cpp b/plugins/feature/gs232controller/gs232controllerworker.cpp index 1de4676a9..cdb18233a 100644 --- a/plugins/feature/gs232controller/gs232controllerworker.cpp +++ b/plugins/feature/gs232controller/gs232controllerworker.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -36,6 +35,9 @@ GS232ControllerWorker::GS232ControllerWorker() : m_running(false), m_mutex(QMutex::Recursive), m_device(nullptr), + m_serialPort(this), + m_socket(this), + m_pollTimer(this), m_lastAzimuth(-1.0f), m_lastElevation(-1.0f), m_spidSetOutstanding(false), diff --git a/plugins/feature/pertester/pertester.cpp b/plugins/feature/pertester/pertester.cpp index 365ad3dc5..3794ffbce 100644 --- a/plugins/feature/pertester/pertester.cpp +++ b/plugins/feature/pertester/pertester.cpp @@ -52,6 +52,7 @@ PERTester::PERTester(WebAPIAdapterInterface *webAPIAdapterInterface) : qDebug("PERTester::PERTester: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new PERTesterWorker(); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "PERTester error"; m_networkManager = new QNetworkAccessManager(); @@ -130,7 +131,9 @@ bool PERTester::handleMessage(const Message& cmd) { MsgReportWorker& report = (MsgReportWorker&) cmd; if (report.getMessage() == "Complete") - m_state = StIdle; + { + stop(); + } else { m_state = StError; diff --git a/plugins/feature/pertester/pertesterworker.cpp b/plugins/feature/pertester/pertesterworker.cpp index ab888f0ac..9f0a0eb8b 100644 --- a/plugins/feature/pertester/pertesterworker.cpp +++ b/plugins/feature/pertester/pertesterworker.cpp @@ -42,6 +42,8 @@ PERTesterWorker::PERTesterWorker() : m_running(false), m_mutex(QMutex::Recursive), m_rxUDPSocket(nullptr), + m_txUDPSocket(this), + m_txTimer(this), m_tx(0), m_rxMatched(0), m_rxUnmatched(0) @@ -66,22 +68,35 @@ bool PERTesterWorker::startWork() { qDebug() << "PERTesterWorker::startWork"; QMutexLocker mutexLocker(&m_mutex); + connect(thread(), SIGNAL(started()), this, SLOT(started())); + connect(thread(), SIGNAL(finished()), this, SLOT(finished())); + m_running = true; + return m_running; +} + +// startWork() is called from main thread. Timers/sockets need to be started on worker thread +void PERTesterWorker::started() +{ openUDP(m_settings); // Automatically restart if previous run had finished, otherwise continue if (m_tx >= m_settings.m_packetCount) resetStats(); connect(&m_txTimer, SIGNAL(timeout()), this, SLOT(tx())); m_txTimer.start(m_settings.m_interval * 1000.0); - m_running = true; - return m_running; + disconnect(thread(), SIGNAL(started()), this, SLOT(started())); } void PERTesterWorker::stopWork() { - QMutexLocker mutexLocker(&m_mutex); + qDebug() << "PERTesterWorker::stopWork"; +} + +void PERTesterWorker::finished() +{ m_txTimer.stop(); closeUDP(); disconnect(&m_txTimer, SIGNAL(timeout()), this, SLOT(tx())); + disconnect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = false; } @@ -314,7 +329,6 @@ void PERTesterWorker::tx() void PERTesterWorker::testComplete() { - stopWork(); if (m_msgQueueToFeature != nullptr) m_msgQueueToFeature->push(PERTester::MsgReportWorker::create("Complete")); qDebug() << "PERTesterWorker::tx: Test complete"; diff --git a/plugins/feature/pertester/pertesterworker.h b/plugins/feature/pertester/pertesterworker.h index 7f6c0110c..2cecaa341 100644 --- a/plugins/feature/pertester/pertesterworker.h +++ b/plugins/feature/pertester/pertesterworker.h @@ -89,6 +89,8 @@ private: void resetStats(); private slots: + void started(); + void finished(); void handleInputMessages(); void rx(); void tx(); diff --git a/plugins/feature/rigctlserver/rigctlserver.cpp b/plugins/feature/rigctlserver/rigctlserver.cpp index 001955497..32716d791 100644 --- a/plugins/feature/rigctlserver/rigctlserver.cpp +++ b/plugins/feature/rigctlserver/rigctlserver.cpp @@ -43,6 +43,7 @@ RigCtlServer::RigCtlServer(WebAPIAdapterInterface *webAPIAdapterInterface) : qDebug("RigCtlServer::RigCtlServer: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new RigCtlServerWorker(webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "RigCtlServer error"; m_networkManager = new QNetworkAccessManager(); diff --git a/plugins/feature/rigctlserver/rigctlserverworker.h b/plugins/feature/rigctlserver/rigctlserverworker.h index bd57495ef..0b5f6e6ce 100644 --- a/plugins/feature/rigctlserver/rigctlserverworker.h +++ b/plugins/feature/rigctlserver/rigctlserverworker.h @@ -20,7 +20,6 @@ #define INCLUDE_FEATURE_RIGCTLSERVERWORKER_H_ #include -#include #include "util/message.h" #include "util/messagequeue.h" diff --git a/plugins/feature/satellitetracker/satellitetracker.cpp b/plugins/feature/satellitetracker/satellitetracker.cpp index 979ec1637..ef596bb40 100644 --- a/plugins/feature/satellitetracker/satellitetracker.cpp +++ b/plugins/feature/satellitetracker/satellitetracker.cpp @@ -51,6 +51,7 @@ SatelliteTracker::SatelliteTracker(WebAPIAdapterInterface *webAPIAdapterInterfac qDebug("SatelliteTracker::SatelliteTracker: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new SatelliteTrackerWorker(this, webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "SatelliteTracker error"; m_networkManager = new QNetworkAccessManager(); diff --git a/plugins/feature/satellitetracker/satellitetrackerworker.cpp b/plugins/feature/satellitetracker/satellitetrackerworker.cpp index fa0a48adb..7560cff2b 100644 --- a/plugins/feature/satellitetracker/satellitetrackerworker.cpp +++ b/plugins/feature/satellitetracker/satellitetrackerworker.cpp @@ -57,6 +57,7 @@ SatelliteTrackerWorker::SatelliteTrackerWorker(SatelliteTracker* satelliteTracke m_msgQueueToGUI(nullptr), m_running(false), m_mutex(QMutex::Recursive), + m_pollTimer(this), m_recalculatePasses(true), m_flipRotation(false), m_extendedAzRotation(false) @@ -79,6 +80,16 @@ bool SatelliteTrackerWorker::startWork() { QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + connect(thread(), SIGNAL(started()), this, SLOT(started())); + connect(thread(), SIGNAL(finished()), this, SLOT(finished())); + m_recalculatePasses = true; + m_running = true; + return m_running; +} + +// startWork() is called from main thread. Timers need to be started on worker thread +void SatelliteTrackerWorker::started() +{ m_pollTimer.start((int)round(m_settings.m_updatePeriod*1000.0)); // Resume doppler timers QHashIterator itr(m_workerState); @@ -89,15 +100,17 @@ bool SatelliteTrackerWorker::startWork() if (satWorkerState->m_dopplerTimer.interval() > 0) satWorkerState->m_dopplerTimer.start(); } - m_recalculatePasses = true; - m_running = true; - return m_running; + disconnect(thread(), SIGNAL(started()), this, SLOT(started())); } void SatelliteTrackerWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); +} + +void SatelliteTrackerWorker::finished() +{ m_pollTimer.stop(); // Stop doppler timers QHashIterator itr(m_workerState); @@ -107,6 +120,7 @@ void SatelliteTrackerWorker::stopWork() itr.value()->m_dopplerTimer.stop(); } m_running = false; + disconnect(thread(), SIGNAL(finished()), this, SLOT(finished())); } void SatelliteTrackerWorker::handleInputMessages() diff --git a/plugins/feature/satellitetracker/satellitetrackerworker.h b/plugins/feature/satellitetracker/satellitetrackerworker.h index e75a0f655..8989f5e61 100644 --- a/plugins/feature/satellitetracker/satellitetrackerworker.h +++ b/plugins/feature/satellitetracker/satellitetrackerworker.h @@ -130,6 +130,8 @@ private: void calculateRotation(SatWorkerState *satWorkerState); private slots: + void started(); + void finished(); void handleInputMessages(); void update(); void aos(SatWorkerState *satWorkerState); diff --git a/plugins/feature/simpleptt/simpleptt.cpp b/plugins/feature/simpleptt/simpleptt.cpp index d8ae88b5f..18a010a10 100644 --- a/plugins/feature/simpleptt/simpleptt.cpp +++ b/plugins/feature/simpleptt/simpleptt.cpp @@ -44,6 +44,7 @@ SimplePTT::SimplePTT(WebAPIAdapterInterface *webAPIAdapterInterface) : { setObjectName(m_featureId); m_worker = new SimplePTTWorker(webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "SimplePTT error"; m_networkManager = new QNetworkAccessManager(); diff --git a/plugins/feature/simpleptt/simplepttworker.cpp b/plugins/feature/simpleptt/simplepttworker.cpp index 6aceb3d56..1e2cc9f7f 100644 --- a/plugins/feature/simpleptt/simplepttworker.cpp +++ b/plugins/feature/simpleptt/simplepttworker.cpp @@ -34,6 +34,7 @@ SimplePTTWorker::SimplePTTWorker(WebAPIAdapterInterface *webAPIAdapterInterface) m_msgQueueToGUI(nullptr), m_running(false), m_tx(false), + m_updateTimer(this), m_mutex(QMutex::Recursive) { qDebug("SimplePTTWorker::SimplePTTWorker"); diff --git a/plugins/feature/startracker/startracker.cpp b/plugins/feature/startracker/startracker.cpp index 0e598f77e..e44ac90fa 100644 --- a/plugins/feature/startracker/startracker.cpp +++ b/plugins/feature/startracker/startracker.cpp @@ -49,6 +49,7 @@ StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) : qDebug("StarTracker::StarTracker: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); m_worker = new StarTrackerWorker(this, webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "StarTracker error"; connect(&m_updatePipesTimer, SIGNAL(timeout()), this, SLOT(updatePipes())); diff --git a/plugins/feature/startracker/startrackerworker.cpp b/plugins/feature/startracker/startrackerworker.cpp index ba577b4d0..10e0314d6 100644 --- a/plugins/feature/startracker/startrackerworker.cpp +++ b/plugins/feature/startracker/startrackerworker.cpp @@ -52,6 +52,7 @@ StarTrackerWorker::StarTrackerWorker(StarTracker* starTracker, WebAPIAdapterInte m_msgQueueToGUI(nullptr), m_running(false), m_mutex(QMutex::Recursive), + m_pollTimer(this), m_tcpServer(nullptr), m_clientConnection(nullptr), m_solarFlux(0.0f) @@ -74,17 +75,30 @@ bool StarTrackerWorker::startWork() { QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); - m_pollTimer.start((int)round(m_settings.m_updatePeriod*1000.0)); + connect(thread(), SIGNAL(started()), this, SLOT(started())); + connect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = true; return m_running; } +// startWork() is called from main thread. Timers/sockets need to be started on worker thread +void StarTrackerWorker::started() +{ + m_pollTimer.start((int)round(m_settings.m_updatePeriod*1000.0)); + disconnect(thread(), SIGNAL(started()), this, SLOT(started())); +} + void StarTrackerWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); +} + +void StarTrackerWorker::finished() +{ restartServer(false, 0); m_pollTimer.stop(); + disconnect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = false; } diff --git a/plugins/feature/startracker/startrackerworker.h b/plugins/feature/startracker/startrackerworker.h index af2122cb6..c7f1b56cc 100644 --- a/plugins/feature/startracker/startrackerworker.h +++ b/plugins/feature/startracker/startrackerworker.h @@ -97,6 +97,8 @@ private: void sendToMap(QList *mapMessageQueues, QString id, QString image, QString text, double lat, double lon, double rotation=0.0); private slots: + void started(); + void finished(); void handleInputMessages(); void update(); void acceptConnection(); diff --git a/plugins/feature/vorlocalizer/vorlocalizer.cpp b/plugins/feature/vorlocalizer/vorlocalizer.cpp index 7bbfcb638..b2e29a337 100644 --- a/plugins/feature/vorlocalizer/vorlocalizer.cpp +++ b/plugins/feature/vorlocalizer/vorlocalizer.cpp @@ -51,6 +51,7 @@ VORLocalizer::VORLocalizer(WebAPIAdapterInterface *webAPIAdapterInterface) : { setObjectName(m_featureId); m_worker = new VorLocalizerWorker(webAPIAdapterInterface); + m_worker->moveToThread(&m_thread); m_state = StIdle; m_errorMessage = "VORLocalizer error"; m_networkManager = new QNetworkAccessManager(); diff --git a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp index 2cb7ac6e2..ebe1cd3e4 100644 --- a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp +++ b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp @@ -42,7 +42,9 @@ VorLocalizerWorker::VorLocalizerWorker(WebAPIAdapterInterface *webAPIAdapterInte m_msgQueueToFeature(nullptr), m_availableChannels(nullptr), m_running(false), - m_mutex(QMutex::Recursive) + m_updateTimer(this), + m_mutex(QMutex::Recursive), + m_rrTimer(this) { qDebug("VorLocalizerWorker::VorLocalizerWorker"); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); @@ -64,17 +66,29 @@ bool VorLocalizerWorker::startWork() QMutexLocker mutexLocker(&m_mutex); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); connect(&m_rrTimer, SIGNAL(timeout()), this, SLOT(rrNextTurn())); - m_rrTimer.start(m_settings.m_rrTime * 1000); + connect(thread(), SIGNAL(started()), this, SLOT(started())); + connect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = true; return m_running; } +// startWork() is called from main thread. Timers/sockets need to be started on worker thread +void VorLocalizerWorker::started() +{ + m_rrTimer.start(m_settings.m_rrTime * 1000); + disconnect(thread(), SIGNAL(started()), this, SLOT(started())); +} void VorLocalizerWorker::stopWork() { QMutexLocker mutexLocker(&m_mutex); + disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); +} + +void VorLocalizerWorker::finished() +{ m_rrTimer.stop(); disconnect(&m_rrTimer, SIGNAL(timeout()), this, SLOT(rrNextTurn())); - disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + disconnect(thread(), SIGNAL(finished()), this, SLOT(finished())); m_running = false; } diff --git a/plugins/feature/vorlocalizer/vorlocalizerworker.h b/plugins/feature/vorlocalizer/vorlocalizerworker.h index 32dfa414d..c6d3c724a 100644 --- a/plugins/feature/vorlocalizer/vorlocalizerworker.h +++ b/plugins/feature/vorlocalizer/vorlocalizerworker.h @@ -167,6 +167,8 @@ private: static void getChannelsByDevice(const QHash *availableChannels, std::vector& m_deviceChannels); private slots: + void started(); + void finished(); void handleInputMessages(); void updateHardware(); void rrNextTurn();