From 39938c5eec677c21cadc3cc44981ba4d5f451350 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Fri, 21 Jan 2022 14:21:11 -0500 Subject: [PATCH 01/13] MAINT: remove QThread inheritance. --- .../mne_scan/libs/scShared/Plugins/abstractplugin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/mne_scan/libs/scShared/Plugins/abstractplugin.h b/src/applications/mne_scan/libs/scShared/Plugins/abstractplugin.h index 03d4f387d88..9e4a8ea14a4 100644 --- a/src/applications/mne_scan/libs/scShared/Plugins/abstractplugin.h +++ b/src/applications/mne_scan/libs/scShared/Plugins/abstractplugin.h @@ -50,7 +50,7 @@ // QT INCLUDES //============================================================================================================= -#include +#include #include #include #include @@ -76,7 +76,7 @@ namespace SCSHAREDLIB * * @brief The AbstractPlugin class is the base interface class of all plugins. */ -class SCSHAREDSHARED_EXPORT AbstractPlugin : public QThread +class SCSHAREDSHARED_EXPORT AbstractPlugin : public QObject { Q_OBJECT From 2d3f5009e2e0c7b8b39cfd70af6f45ea2bf42f1b Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Fri, 21 Jan 2022 14:59:19 -0500 Subject: [PATCH 02/13] Proof of concept with std::thread --- .../plugins/fiffsimulator/fiffsimulator.cpp | 22 +++++++++++++------ .../plugins/fiffsimulator/fiffsimulator.h | 6 +++++ .../fiffsimulator/fiffsimulatorproducer.cpp | 2 +- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp index e09b7004867..6ba620ea055 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp @@ -46,6 +46,7 @@ #include #include #include +#include //============================================================================================================= // QT INCLUDES @@ -56,6 +57,7 @@ #include #include #include +#include #include @@ -85,6 +87,8 @@ FiffSimulator::FiffSimulator() , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_float(40))) , m_pRtCmdClient(QSharedPointer::create()) , m_iDefaultPortCmdClient(4217) +, m_OutputProcessingThreadRunning(false) +, m_StopOutputProcessingThread(false) { //init channels when fiff info is available connect(this, &FiffSimulator::fiffInfoAvailable, @@ -95,7 +99,7 @@ FiffSimulator::FiffSimulator() FiffSimulator::~FiffSimulator() { - if(m_pFiffSimulatorProducer->isRunning() || this->isRunning()) { + if(m_pFiffSimulatorProducer->isRunning() || m_OutputProcessingThreadRunning) { stop(); } } @@ -148,13 +152,14 @@ bool FiffSimulator::start() m_pFiffSimulatorProducer->start(); // Wait one sec so the producer can update the m_iDataClientId accordingly - msleep(1000); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // Start Measurement at mne_rt_server (*m_pRtCmdClient)["start"].pValues()[0].setValue(m_pFiffSimulatorProducer->m_iDataClientId); (*m_pRtCmdClient)["start"].send(); - QThread::start(); + m_OutputProcessingThread = std::thread(&FiffSimulator::run, this); + m_OutputProcessingThreadRunning = true; return true; } @@ -167,8 +172,9 @@ bool FiffSimulator::start() bool FiffSimulator::stop() { // Stop this (consumer) thread first - requestInterruption(); - wait(500); + m_StopOutputProcessingThread = true; + m_OutputProcessingThread.join(); + m_OutputProcessingThreadRunning = false; // Stop producer thread second m_pFiffSimulatorProducer->stop(); @@ -182,6 +188,8 @@ bool FiffSimulator::stop() m_pRTMSA_FiffSimulator->measurementData()->clear(); m_pCircularBuffer->clear(); + m_StopOutputProcessingThread = false; + return true; } @@ -214,11 +222,11 @@ void FiffSimulator::run() { MatrixXf matValue; - while(!isInterruptionRequested()) { + while(!m_StopOutputProcessingThread) { //pop matrix if(m_pCircularBuffer->pop(matValue)) { //emit values - if(!isInterruptionRequested()) { + if(!m_StopOutputProcessingThread) { m_pRTMSA_FiffSimulator->measurementData()->setValue(matValue.cast()); } } diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.h b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.h index 0f734b64421..bd740a877bd 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.h +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.h @@ -45,6 +45,8 @@ #include #include #include +#include +#include //============================================================================================================= // QT INCLUDES @@ -212,6 +214,10 @@ class FIFFSIMULATORSHARED_EXPORT FiffSimulator : public SCSHAREDLIB::AbstractSen QMutex m_qMutex; /**< The mutex to ensure thread safety.*/ + std::thread m_OutputProcessingThread; + std::atomic_bool m_OutputProcessingThreadRunning; + std::atomic_bool m_StopOutputProcessingThread; + signals: //========================================================================================================= /** diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.cpp b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.cpp index 94565a172c0..f523fc326eb 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.cpp +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.cpp @@ -178,7 +178,7 @@ void FiffSimulatorProducer::run() m_producerMutex.unlock(); // Only perform data reading if the measurement was started - if(m_pFiffSimulator->isRunning()) { + if(m_pFiffSimulator->m_OutputProcessingThreadRunning) { m_pRtDataClient->readRawBuffer(m_pFiffSimulator->m_pFiffInfo->nchan, matData, kind); From 72e13080d6cc3fedecd5b6b9f6328780d1177191 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Fri, 21 Jan 2022 16:02:13 -0500 Subject: [PATCH 03/13] ENH: add thread class --- .../mne_scan/libs/scShared/Plugins/threads.h | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/applications/mne_scan/libs/scShared/Plugins/threads.h diff --git a/src/applications/mne_scan/libs/scShared/Plugins/threads.h b/src/applications/mne_scan/libs/scShared/Plugins/threads.h new file mode 100644 index 00000000000..ea52dbb206c --- /dev/null +++ b/src/applications/mne_scan/libs/scShared/Plugins/threads.h @@ -0,0 +1,102 @@ +//============================================================================================================= +/** + * @file threads.h + * @author Gabriel Motta + * @since 0.1.9 + * @date January, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains threading classes. + * + */ + +#ifndef MNESCAN_THREADS_H +#define MNESCAN_THREADS_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include +#include +#include + +//============================================================================================================= +// DEFINE NAMESPACE SCSHAREDLIB +//============================================================================================================= + +namespace SCSHAREDLIB +{ + +class Thread +{ +public: + //========================================================================================================= + /** + * Constructs an "empty" object. + */ + Thread(): m_bIsRunning(false), m_bTriggerStop(false) {}; + + + template + //========================================================================================================= + /** + * Constructs a thread object to run a function in a separate thread. + * + * @param[in] func function to be run in separate thread + * @param[in] args function arguments. + * (Note - member functions need to be passed usually-implicit 'this' pointer) + */ + Thread(Function&& func, Args&&... args): m_thread(func, args...), m_bIsRunning(true), m_bTriggerStop(false){} + + //========================================================================================================= + /** + * Returns whether the thread is running. + */ + bool isRunning() const {return m_bIsRunning;} + + //========================================================================================================= + /** + * Returns whether a stop has been triggered. + */ + bool stopTriggered() const {return m_bTriggerStop;} + + //========================================================================================================= + /** + * Attempts to join thread. Underlying function needs to finish before this happens. + * Recommend using the 'stopTriggered' method to check, similarly to 'interruptionRequested' + */ + void stop() {m_bTriggerStop = true; m_thread.join(); m_bIsRunning = false;} + +private: + std::thread m_thread; /**< The actual thread. */ + std::atomic_bool m_bIsRunning; /**< Whether the thred is runing. */ + std::atomic_bool m_bTriggerStop; /**< Whether a thread interruption has been requested. */ +}; + + +}//namespace + +#endif // MNESCAN_THREADS_H From 88a0da21bbf0eecfec7c9f8e2a9d41153687817e Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Fri, 21 Jan 2022 16:15:58 -0500 Subject: [PATCH 04/13] ENH: static function for running function in separate thread --- src/applications/mne_scan/libs/scShared/Plugins/threads.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/applications/mne_scan/libs/scShared/Plugins/threads.h b/src/applications/mne_scan/libs/scShared/Plugins/threads.h index ea52dbb206c..8920fcbf062 100644 --- a/src/applications/mne_scan/libs/scShared/Plugins/threads.h +++ b/src/applications/mne_scan/libs/scShared/Plugins/threads.h @@ -90,6 +90,13 @@ class Thread */ void stop() {m_bTriggerStop = true; m_thread.join(); m_bIsRunning = false;} + //========================================================================================================= + /** + * Runs a function as a thread. Thread is deleted once function is finished. Not bound by caller's scope. + */ + template + static void run(Function&& func, Args&&... args){Thread(func, args...).m_thread.detach();} + private: std::thread m_thread; /**< The actual thread. */ std::atomic_bool m_bIsRunning; /**< Whether the thred is runing. */ From b75e4c8c1127a25a4959b60ca9d7201b457a5290 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Mon, 24 Jan 2022 11:01:56 -0500 Subject: [PATCH 05/13] MAINT: single responsability - thread is only a thread. --- .../mne_scan/libs/scShared/Plugins/threads.h | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/applications/mne_scan/libs/scShared/Plugins/threads.h b/src/applications/mne_scan/libs/scShared/Plugins/threads.h index 8920fcbf062..b153f013830 100644 --- a/src/applications/mne_scan/libs/scShared/Plugins/threads.h +++ b/src/applications/mne_scan/libs/scShared/Plugins/threads.h @@ -57,7 +57,7 @@ class Thread /** * Constructs an "empty" object. */ - Thread(): m_bIsRunning(false), m_bTriggerStop(false) {}; + Thread(): m_bIsRunning(false) {} template @@ -69,7 +69,7 @@ class Thread * @param[in] args function arguments. * (Note - member functions need to be passed usually-implicit 'this' pointer) */ - Thread(Function&& func, Args&&... args): m_thread(func, args...), m_bIsRunning(true), m_bTriggerStop(false){} + Thread(Function&& func, Args&&... args): m_thread(func, args...), m_bIsRunning(true) {} //========================================================================================================= /** @@ -77,19 +77,6 @@ class Thread */ bool isRunning() const {return m_bIsRunning;} - //========================================================================================================= - /** - * Returns whether a stop has been triggered. - */ - bool stopTriggered() const {return m_bTriggerStop;} - - //========================================================================================================= - /** - * Attempts to join thread. Underlying function needs to finish before this happens. - * Recommend using the 'stopTriggered' method to check, similarly to 'interruptionRequested' - */ - void stop() {m_bTriggerStop = true; m_thread.join(); m_bIsRunning = false;} - //========================================================================================================= /** * Runs a function as a thread. Thread is deleted once function is finished. Not bound by caller's scope. @@ -100,10 +87,8 @@ class Thread private: std::thread m_thread; /**< The actual thread. */ std::atomic_bool m_bIsRunning; /**< Whether the thred is runing. */ - std::atomic_bool m_bTriggerStop; /**< Whether a thread interruption has been requested. */ }; - }//namespace #endif // MNESCAN_THREADS_H From 497df8ea809d6b621f56f8975fe0d97516774ff9 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Mon, 24 Jan 2022 11:38:55 -0500 Subject: [PATCH 06/13] ENH: convert averaging plugin --- .../mne_scan/plugins/averaging/averaging.cpp | 14 ++++++++------ .../mne_scan/plugins/averaging/averaging.h | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/applications/mne_scan/plugins/averaging/averaging.cpp b/src/applications/mne_scan/plugins/averaging/averaging.cpp index 7aae3b63df6..8f9d185f969 100644 --- a/src/applications/mne_scan/plugins/averaging/averaging.cpp +++ b/src/applications/mne_scan/plugins/averaging/averaging.cpp @@ -77,6 +77,7 @@ using namespace Eigen; Averaging::Averaging() : m_pCircularBuffer(CircularBuffer::SPtr::create(40)) +, m_bProcessOutput(false) { } @@ -84,7 +85,7 @@ Averaging::Averaging() Averaging::~Averaging() { - if(this->isRunning()) + if(m_OutputProcessingThread.joinable()) stop(); } @@ -106,7 +107,8 @@ void Averaging::unload() bool Averaging::start() { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&Averaging::run, this); return true; } @@ -115,8 +117,8 @@ bool Averaging::start() bool Averaging::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + m_OutputProcessingThread.join(); m_bPluginControlWidgetsInit = false; @@ -406,7 +408,7 @@ void Averaging::onChangeBaselineActive(bool state) void Averaging::onNewEvokedSet(const FIFFLIB::FiffEvokedSet& evokedSet, const QStringList& lResponsibleTriggerTypes) { - if(!this->isRunning()) { + if(!m_bProcessOutput) { return; } @@ -439,7 +441,7 @@ void Averaging::run() FIFFLIB::FiffEvokedSet evokedSet; QStringList lResponsibleTriggerTypes; - while(!isInterruptionRequested()){ + while(m_bProcessOutput){ if(m_pCircularBuffer->pop(evokedSet)) { m_qMutex.lock(); lResponsibleTriggerTypes = m_lResponsibleTriggerTypes; diff --git a/src/applications/mne_scan/plugins/averaging/averaging.h b/src/applications/mne_scan/plugins/averaging/averaging.h index 5b89f78a7ad..629e2432a79 100644 --- a/src/applications/mne_scan/plugins/averaging/averaging.h +++ b/src/applications/mne_scan/plugins/averaging/averaging.h @@ -47,6 +47,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -237,6 +239,9 @@ class AVERAGINGSHARED_EXPORT Averaging : public SCSHAREDLIB::AbstractAlgorithm QMap m_mapStimChsIndexNames; /**< The currently available stim channels and their corresponding index in the data. */ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; + signals: void stimChannelsChanged(const QMap& mapStimChsIndexNames); void fiffChInfoChanged(const QList& fiffChInfoList); From aed0d6d18d6b15a9c3c8e4af6dcdda9f8d931cf5 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 11:37:41 -0500 Subject: [PATCH 07/13] MAINT: onverting covariance plugin --- .../mne_scan/plugins/averaging/averaging.cpp | 2 +- .../mne_scan/plugins/covariance/covariance.cpp | 15 +++++++++------ .../mne_scan/plugins/covariance/covariance.h | 5 +++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/applications/mne_scan/plugins/averaging/averaging.cpp b/src/applications/mne_scan/plugins/averaging/averaging.cpp index 8f9d185f969..f497b03b651 100644 --- a/src/applications/mne_scan/plugins/averaging/averaging.cpp +++ b/src/applications/mne_scan/plugins/averaging/averaging.cpp @@ -85,7 +85,7 @@ Averaging::Averaging() Averaging::~Averaging() { - if(m_OutputProcessingThread.joinable()) + if(m_bProcessOutput) stop(); } diff --git a/src/applications/mne_scan/plugins/covariance/covariance.cpp b/src/applications/mne_scan/plugins/covariance/covariance.cpp index 842f28d6876..35b5a908685 100644 --- a/src/applications/mne_scan/plugins/covariance/covariance.cpp +++ b/src/applications/mne_scan/plugins/covariance/covariance.cpp @@ -89,7 +89,7 @@ Covariance::Covariance() Covariance::~Covariance() { - if(this->isRunning()) + if(m_bProcessOutput) stop(); } @@ -158,7 +158,8 @@ void Covariance::unload() bool Covariance::start() { // Start thread - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&Covariance::run, this); return true; } @@ -167,8 +168,10 @@ bool Covariance::start() bool Covariance::stop() { - requestInterruption(); - wait(500); + if(m_OutputProcessingThread.joinable()){ + m_bProcessOutput = false; + m_OutputProcessingThread.join(); + } m_bPluginControlWidgetsInit = false; @@ -249,7 +252,7 @@ void Covariance::run() break; } m_mutex.unlock(); - msleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } MatrixXd matData; @@ -260,7 +263,7 @@ void Covariance::run() RTPROCESSINGLIB::RtCov rtCov(m_pFiffInfo); // Start processing data - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { // Get the current data if(m_pCircularBuffer->pop(matData)) { m_mutex.lock(); diff --git a/src/applications/mne_scan/plugins/covariance/covariance.h b/src/applications/mne_scan/plugins/covariance/covariance.h index bb58b634d45..f268f63c012 100644 --- a/src/applications/mne_scan/plugins/covariance/covariance.h +++ b/src/applications/mne_scan/plugins/covariance/covariance.h @@ -45,6 +45,8 @@ #include #include +#include + //============================================================================================================= // EIGEN INCLUDES //============================================================================================================= @@ -164,6 +166,9 @@ class COVARIANCESHARED_EXPORT Covariance : public SCSHAREDLIB::AbstractAlgorithm QSharedPointer > m_pCovarianceInput; /**< The RealTimeMultiSampleArray of the Covariance input.*/ QSharedPointer > m_pCovarianceOutput; /**< The RealTimeCov of the Covariance output.*/ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; + signals: }; } // NAMESPACE From 7d75371fd9909f84d553161b2ca412102c255c3b Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 11:47:36 -0500 Subject: [PATCH 08/13] ENH: change stop logic and convert hpi --- .../mne_scan/plugins/averaging/averaging.cpp | 5 ++++- .../mne_scan/plugins/covariance/covariance.cpp | 3 ++- .../plugins/fiffsimulator/fiffsimulator.cpp | 8 +++++--- src/applications/mne_scan/plugins/hpi/hpi.cpp | 18 ++++++++++++------ src/applications/mne_scan/plugins/hpi/hpi.h | 5 +++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/applications/mne_scan/plugins/averaging/averaging.cpp b/src/applications/mne_scan/plugins/averaging/averaging.cpp index f497b03b651..0861c24b41d 100644 --- a/src/applications/mne_scan/plugins/averaging/averaging.cpp +++ b/src/applications/mne_scan/plugins/averaging/averaging.cpp @@ -118,7 +118,10 @@ bool Averaging::start() bool Averaging::stop() { m_bProcessOutput = false; - m_OutputProcessingThread.join(); + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_bPluginControlWidgetsInit = false; diff --git a/src/applications/mne_scan/plugins/covariance/covariance.cpp b/src/applications/mne_scan/plugins/covariance/covariance.cpp index 35b5a908685..63ffd03d172 100644 --- a/src/applications/mne_scan/plugins/covariance/covariance.cpp +++ b/src/applications/mne_scan/plugins/covariance/covariance.cpp @@ -168,8 +168,9 @@ bool Covariance::start() bool Covariance::stop() { + m_bProcessOutput = false; + if(m_OutputProcessingThread.joinable()){ - m_bProcessOutput = false; m_OutputProcessingThread.join(); } diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp index 6ba620ea055..31cda8978e8 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp @@ -172,9 +172,11 @@ bool FiffSimulator::start() bool FiffSimulator::stop() { // Stop this (consumer) thread first - m_StopOutputProcessingThread = true; - m_OutputProcessingThread.join(); - m_OutputProcessingThreadRunning = false; + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } // Stop producer thread second m_pFiffSimulatorProducer->stop(); diff --git a/src/applications/mne_scan/plugins/hpi/hpi.cpp b/src/applications/mne_scan/plugins/hpi/hpi.cpp index c3b2f975b50..f38706fe5b6 100644 --- a/src/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/src/applications/mne_scan/plugins/hpi/hpi.cpp @@ -106,8 +106,8 @@ Hpi::Hpi() Hpi::~Hpi() { - if(isRunning()) { - resetState(); + if(m_bProcessOutput) { + stop(); } } @@ -145,7 +145,9 @@ void Hpi::unload() bool Hpi::start() { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&Hpi::run, this); + return true; } @@ -154,7 +156,11 @@ bool Hpi::start() bool Hpi::stop() { - requestInterruption(); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } resetState(); return true; } @@ -545,7 +551,7 @@ void Hpi::run() if(bFiffInfo) { break; } - msleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } // init hpi fit @@ -583,7 +589,7 @@ void Hpi::run() MatrixXd matDataMerged(m_pFiffInfo->chs.size(), fittingWindowSize); bool bOrder = false; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { m_mutex.lock(); if(fittingWindowSize != m_iFittingWindowSize) { fittingWindowSize = m_iFittingWindowSize; diff --git a/src/applications/mne_scan/plugins/hpi/hpi.h b/src/applications/mne_scan/plugins/hpi/hpi.h index 83b0f332ab9..47f17d26dfb 100644 --- a/src/applications/mne_scan/plugins/hpi/hpi.h +++ b/src/applications/mne_scan/plugins/hpi/hpi.h @@ -47,6 +47,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -320,6 +322,9 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm SCSHAREDLIB::PluginInputData::SPtr m_pHpiInput; /**< The RealTimeMultiSampleArray of the Hpi input.*/ SCSHAREDLIB::PluginOutputData::SPtr m_pHpiOutput; /**< The RealTimeHpiResult of the Hpi output.*/ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; + signals: void errorsChanged(const QVector& vErrors, double dMeanErrorDist); From 9cc2d1d21bac9aa64ef62d171730851758acd0fa Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 11:51:01 -0500 Subject: [PATCH 09/13] MAINT: convert other algorithm plugins --- .../neuronalconnectivity.cpp | 18 +++++++---- .../neuronalconnectivity.h | 5 +++ .../plugins/noisereduction/noisereduction.cpp | 16 ++++++---- .../plugins/noisereduction/noisereduction.h | 4 +++ .../mne_scan/plugins/rtcmne/rtcmne.cpp | 32 +++++++++++-------- .../mne_scan/plugins/rtcmne/rtcmne.h | 5 +++ .../mne_scan/plugins/rtfwd/rtfwd.cpp | 16 ++++++---- .../mne_scan/plugins/rtfwd/rtfwd.h | 5 +++ .../plugins/writetofile/writetofile.cpp | 14 +++++--- .../plugins/writetofile/writetofile.h | 5 +++ 10 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp index 9a2aa749cbe..5fc59175815 100644 --- a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp +++ b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp @@ -109,7 +109,7 @@ NeuronalConnectivity::NeuronalConnectivity() NeuronalConnectivity::~NeuronalConnectivity() { - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } } @@ -195,7 +195,8 @@ void NeuronalConnectivity::unload() bool NeuronalConnectivity::start() { //Start thread - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&NeuronalConnectivity::run, this); return true; } @@ -206,8 +207,11 @@ bool NeuronalConnectivity::stop() { m_pRtConnectivity->restart(); - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_bPluginControlWidgetsInit = false; @@ -510,13 +514,13 @@ void NeuronalConnectivity::run() break; } m_mutex.unlock(); - msleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } int skip_count = 0; Network network; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { //Do processing after skip count has reached limit if((skip_count % m_iDownSample) == 0) { if(m_pCircularBuffer->pop(network)) { @@ -562,7 +566,7 @@ void NeuronalConnectivity::onMetricChanged(const QString& sMetric) m_sConnectivityMethods = QStringList() << sMetric; m_connectivitySettings.setConnectivityMethods(m_sConnectivityMethods); - if(m_pRtConnectivity && this->isRunning()) { + if(m_pRtConnectivity && m_bProcessOutput) { m_pRtConnectivity->restart(); m_pRtConnectivity->append(m_connectivitySettings); } diff --git a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h index 4d97e087ba0..a175a1904b0 100644 --- a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h +++ b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h @@ -49,6 +49,8 @@ #include #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -272,6 +274,9 @@ class NEURONALCONNECTIVITYSHARED_EXPORT NeuronalConnectivity : public SCSHAREDLI Eigen::RowVectorXi m_vecPicks; /**< The picked data channels. */ CONNECTIVITYLIB::Network m_currentConnectivityResult; /**< The current connectivity result.*/ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp b/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp index 92882f69f60..e7479cddf89 100644 --- a/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp +++ b/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp @@ -111,7 +111,7 @@ NoiseReduction::NoiseReduction() NoiseReduction::~NoiseReduction() { - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } } @@ -159,8 +159,11 @@ bool NoiseReduction::start() bool NoiseReduction::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_iMaxFilterTapSize = -1; @@ -224,7 +227,8 @@ void NoiseReduction::update(SCMEASLIB::Measurement::SPtr pMeasurement) if(m_iMaxFilterTapSize == -1) { m_iMaxFilterTapSize = pRTMSA->getMultiSampleArray().first().cols(); initPluginControlWidgets(); - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&NoiseReduction::run, this); } for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) { @@ -345,7 +349,7 @@ void NoiseReduction::run() MatrixXd matData; QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { // Get the current data if(m_pCircularBuffer->pop(matData)) { m_mutex.lock(); @@ -409,7 +413,7 @@ void NoiseReduction::run() m_mutex.unlock(); //Send the data to the connected plugins and the display - if(!isInterruptionRequested()) { + if(m_bProcessOutput) { m_pNoiseReductionOutput->measurementData()->setValue(matData); } } diff --git a/src/applications/mne_scan/plugins/noisereduction/noisereduction.h b/src/applications/mne_scan/plugins/noisereduction/noisereduction.h index e6e6c0dc2cd..0f2276cd527 100644 --- a/src/applications/mne_scan/plugins/noisereduction/noisereduction.h +++ b/src/applications/mne_scan/plugins/noisereduction/noisereduction.h @@ -50,6 +50,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -263,6 +265,8 @@ class NOISEREDUCTIONSHARED_EXPORT NoiseReduction : public SCSHAREDLIB::AbstractA SCSHAREDLIB::PluginInputData::SPtr m_pNoiseReductionInput; /**< The RealTimeMultiSampleArray of the NoiseReduction input.*/ SCSHAREDLIB::PluginOutputData::SPtr m_pNoiseReductionOutput; /**< The RealTimeMultiSampleArray of the NoiseReduction output.*/ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; signals: }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp index 6c8a43e16de..ce3c1bf44ea 100644 --- a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp +++ b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp @@ -115,7 +115,7 @@ RtcMne::~RtcMne() { m_future.waitForFinished(); - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } } @@ -313,7 +313,8 @@ bool RtcMne::calcFiffInfo() bool RtcMne::start() { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&RtcMne::run, this); return true; } @@ -321,8 +322,11 @@ bool RtcMne::start() bool RtcMne::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_qListCovChNames.clear(); m_bEvokedInput = false; @@ -369,7 +373,7 @@ void RtcMne::updateRTFS(SCMEASLIB::Measurement::SPtr pMeasurement) m_qMutex.unlock(); // update inverse operator - if(this->isRunning() && m_pRtInvOp) { + if(m_bProcessOutput && m_pRtInvOp) { m_pRtInvOp->setFwdSolution(m_pFwd); m_pRtInvOp->append(*m_pNoiseCov); } @@ -386,7 +390,7 @@ void RtcMne::updateRTMSA(SCMEASLIB::Measurement::SPtr pMeasurement) if(m_pFwd) { QSharedPointer pRTMSA = pMeasurement.dynamicCast(); - if(pRTMSA && this->isRunning()) { + if(pRTMSA && m_bProcessOutput) { //Fiff Information of the RTMSA m_qMutex.lock(); if(!m_pFiffInfoInput) { @@ -400,7 +404,7 @@ void RtcMne::updateRTMSA(SCMEASLIB::Measurement::SPtr pMeasurement) initPluginControlWidgets(); } - if(this->isRunning()) { + if(m_bProcessOutput) { // Check for artifacts QMap mapReject; mapReject.insert("eog", 150e-06); @@ -433,7 +437,7 @@ void RtcMne::updateRTC(SCMEASLIB::Measurement::SPtr pMeasurement) if(m_pFwd) { QSharedPointer pRTC = pMeasurement.dynamicCast(); - if(pRTC && this->isRunning()) { + if(pRTC && m_bProcessOutput) { // Init Real-Time inverse estimator if(!m_pRtInvOp && m_pFiffInfo && m_pFwd) { m_pRtInvOp = RtInvOp::SPtr(new RtInvOp(m_pFiffInfo, m_pFwd)); @@ -446,7 +450,7 @@ void RtcMne::updateRTC(SCMEASLIB::Measurement::SPtr pMeasurement) m_qListCovChNames = pRTC->getValue()->names; } - if(this->isRunning() && m_pRtInvOp){ + if(m_bProcessOutput && m_pRtInvOp){ m_pNoiseCov = pRTC->getValue(); m_pRtInvOp->append(*m_pNoiseCov); } @@ -467,7 +471,7 @@ void RtcMne::updateRTE(SCMEASLIB::Measurement::SPtr pMeasurement) initPluginControlWidgets(); } - if(!this->isRunning() || !lResponsibleTriggerTypes.contains(m_sAvrType)) { + if(!m_bProcessOutput || !lResponsibleTriggerTypes.contains(m_sAvrType)) { return; } @@ -491,7 +495,7 @@ void RtcMne::updateRTE(SCMEASLIB::Measurement::SPtr pMeasurement) initPluginControlWidgets(); } - if(this->isRunning()) { + if(m_bProcessOutput) { for(int i = 0; i < pFiffEvokedSet->evoked.size(); ++i) { if(pFiffEvokedSet->evoked.at(i).comment == m_sAvrType) { // Store current evoked as member so we can dispatch it if the time pick by the user changed @@ -551,7 +555,7 @@ void RtcMne::onTimePointValueChanged(int iTimePointMs) m_iTimePointSps = m_pFiffInfoInput->sfreq * (float)iTimePointMs * 0.001f; m_qMutex.unlock(); - if(this->isRunning()) { + if(m_bProcessOutput) { while(!m_pCircularEvokedBuffer->push(m_currentEvoked)) { //Do nothing until the circular buffer is ready to accept new data again } @@ -565,7 +569,7 @@ void RtcMne::run() { // Wait for fiff info to arrive while(!calcFiffInfo()) { - msleep(200); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } // Init parameters @@ -588,7 +592,7 @@ void RtcMne::run() QStringList lChNamesInvOp; // Start processing data - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { m_qMutex.lock(); iTimePointSps = m_iTimePointSps; bEvokedInput = m_bEvokedInput; diff --git a/src/applications/mne_scan/plugins/rtcmne/rtcmne.h b/src/applications/mne_scan/plugins/rtcmne/rtcmne.h index 83c36037120..fa3c2cf0faf 100644 --- a/src/applications/mne_scan/plugins/rtcmne/rtcmne.h +++ b/src/applications/mne_scan/plugins/rtcmne/rtcmne.h @@ -50,6 +50,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -265,6 +267,9 @@ class RTCMNESHARED_EXPORT RtcMne : public SCSHAREDLIB::AbstractAlgorithm MNELIB::MNEInverseOperator m_invOp; /**< The inverse operator. */ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; + signals: void responsibleTriggerTypesChanged(const QStringList& lResponsibleTriggerTypes); diff --git a/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp b/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp index aa9ddf85461..1b9c55fd56d 100644 --- a/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp +++ b/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp @@ -115,7 +115,7 @@ RtFwd::~RtFwd() { m_future.waitForFinished(); - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } } @@ -222,7 +222,8 @@ bool RtFwd::start() stream->close(); //Start thread - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&RtFwd::run, this); return true; } @@ -231,8 +232,11 @@ bool RtFwd::start() bool RtFwd::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_bPluginControlWidgetsInit = false; @@ -400,7 +404,7 @@ void RtFwd::run() break; } m_mutex.unlock(); - msleep(200); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } m_mutex.lock(); @@ -429,7 +433,7 @@ void RtFwd::run() bool bDoFwdComputation = false; // compute forward if requested bool bIsInit = false; // only recompute if initial fwd solulion is calculated - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { m_mutex.lock(); bDoFwdComputation = m_bDoFwdComputation; m_mutex.unlock(); diff --git a/src/applications/mne_scan/plugins/rtfwd/rtfwd.h b/src/applications/mne_scan/plugins/rtfwd/rtfwd.h index f92c168b13a..01ef07fe5ce 100644 --- a/src/applications/mne_scan/plugins/rtfwd/rtfwd.h +++ b/src/applications/mne_scan/plugins/rtfwd/rtfwd.h @@ -49,6 +49,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -224,6 +226,9 @@ class RTFWDSHARED_EXPORT RtFwd : public SCSHAREDLIB::AbstractAlgorithm SCSHAREDLIB::PluginOutputData::SPtr m_pRTFSOutput; /**< The fwd solution.*/ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; + signals: //========================================================================================================= /** diff --git a/src/applications/mne_scan/plugins/writetofile/writetofile.cpp b/src/applications/mne_scan/plugins/writetofile/writetofile.cpp index 3b8f7f72b60..1ef213112c8 100644 --- a/src/applications/mne_scan/plugins/writetofile/writetofile.cpp +++ b/src/applications/mne_scan/plugins/writetofile/writetofile.cpp @@ -111,7 +111,7 @@ WriteToFile::WriteToFile() WriteToFile::~WriteToFile() { - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } } @@ -145,7 +145,8 @@ void WriteToFile::unload() bool WriteToFile::start() { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&WriteToFile::run, this); return true; } @@ -154,8 +155,11 @@ bool WriteToFile::start() bool WriteToFile::stop() { - requestInterruption(); - wait(); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_bPluginControlWidgetsInit = false; @@ -293,7 +297,7 @@ void WriteToFile::run() MatrixXd matData; qint32 size = 0; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { if(m_pCircularBuffer) { //pop matrix diff --git a/src/applications/mne_scan/plugins/writetofile/writetofile.h b/src/applications/mne_scan/plugins/writetofile/writetofile.h index 1530c89d7b7..e849fe28230 100644 --- a/src/applications/mne_scan/plugins/writetofile/writetofile.h +++ b/src/applications/mne_scan/plugins/writetofile/writetofile.h @@ -46,6 +46,8 @@ #include #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -310,6 +312,9 @@ class WRITETOFILESHARED_EXPORT WriteToFile : public SCSHAREDLIB::AbstractAlgorit FIFFLIB::FiffFileSharer m_FileSharer; /**< Handles copying recording file and saving copy to shared directory. */ QStringList m_lFileNames; /**< List of file names of latest recording */ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE From 18f0d33128539836f49108ad773819c657666cc2 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 13:56:34 -0500 Subject: [PATCH 10/13] MAINT: add missing initilizations of bools. --- .../mne_scan/plugins/averaging/averaging.h | 1 + .../mne_scan/plugins/babymeg/babymeg.cpp | 19 ++++++++++++------- .../mne_scan/plugins/babymeg/babymeg.h | 5 +++++ .../mne_scan/plugins/brainamp/brainamp.cpp | 1 + .../mne_scan/plugins/brainamp/brainamp.h | 6 ++++++ .../plugins/covariance/covariance.cpp | 1 + .../mne_scan/plugins/covariance/covariance.h | 1 + src/applications/mne_scan/plugins/hpi/hpi.cpp | 1 + src/applications/mne_scan/plugins/hpi/hpi.h | 1 + .../neuronalconnectivity.cpp | 1 + .../neuronalconnectivity.h | 1 + .../plugins/noisereduction/noisereduction.cpp | 1 + .../plugins/noisereduction/noisereduction.h | 1 + .../mne_scan/plugins/rtcmne/rtcmne.cpp | 1 + .../mne_scan/plugins/rtcmne/rtcmne.h | 1 + .../mne_scan/plugins/rtfwd/rtfwd.cpp | 1 + .../mne_scan/plugins/rtfwd/rtfwd.h | 1 + .../plugins/writetofile/writetofile.cpp | 1 + .../plugins/writetofile/writetofile.h | 1 + 19 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/applications/mne_scan/plugins/averaging/averaging.h b/src/applications/mne_scan/plugins/averaging/averaging.h index 629e2432a79..7f404c98da6 100644 --- a/src/applications/mne_scan/plugins/averaging/averaging.h +++ b/src/applications/mne_scan/plugins/averaging/averaging.h @@ -48,6 +48,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/babymeg/babymeg.cpp b/src/applications/mne_scan/plugins/babymeg/babymeg.cpp index 533152be07b..4be61037d08 100644 --- a/src/applications/mne_scan/plugins/babymeg/babymeg.cpp +++ b/src/applications/mne_scan/plugins/babymeg/babymeg.cpp @@ -88,6 +88,7 @@ BabyMEG::BabyMEG() , m_sFiffProjections(QCoreApplication::applicationDirPath() + "/../resources/mne_scan/plugins/babymeg/header.fif") , m_sFiffCompensators(QCoreApplication::applicationDirPath() + "/../resources/mne_scan/plugins/babymeg/compensator.fif") , m_sBadChannels(QCoreApplication::applicationDirPath() + "/../resources/mne_scan/plugins/babymeg/both.bad") +, m_bProcessOutput(false) { m_pActionSqdCtrl = new QAction(QIcon(":/images/sqdctrl.png"), tr("Squid Control"),this); // m_pActionSetupProject->setShortcut(tr("F12")); @@ -107,7 +108,7 @@ BabyMEG::BabyMEG() BabyMEG::~BabyMEG() { - if(this->isRunning()) { + if(m_bProcessOutput) { stop(); } @@ -208,7 +209,8 @@ bool BabyMEG::start() initConnector(); // Start thread - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&BabyMEG::run, this); return true; } @@ -217,8 +219,11 @@ bool BabyMEG::start() bool BabyMEG::stop() { - requestInterruption(); - wait(2000); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } // Clear all data in the buffer connected to displays and other plugins m_pRTMSABabyMEG->measurementData()->clear(); @@ -260,13 +265,13 @@ void BabyMEG::run() { MatrixXf matValue; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { //pop matrix if(m_pCircularBuffer->pop(matValue)) { //Create digital trigger information createDigTrig(matValue); - if(!isInterruptionRequested()) { + if(m_bProcessOutput) { m_pRTMSABabyMEG->measurementData()->setValue(this->calibrate(matValue)); } } @@ -352,7 +357,7 @@ void BabyMEG::setFiffData(QByteArray data) IOUtils::swap_floatp(rawData.data()+i); } - if(this->isRunning()) { + if(m_bProcessOutput) { while(!m_pCircularBuffer->push(rawData)) { //Do nothing until the circular buffer is ready to accept new data again } diff --git a/src/applications/mne_scan/plugins/babymeg/babymeg.h b/src/applications/mne_scan/plugins/babymeg/babymeg.h index f91001fc508..ec492b173e4 100644 --- a/src/applications/mne_scan/plugins/babymeg/babymeg.h +++ b/src/applications/mne_scan/plugins/babymeg/babymeg.h @@ -50,6 +50,9 @@ #include #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -319,6 +322,8 @@ class BABYMEGSHARED_EXPORT BabyMEG : public SCSHAREDLIB::AbstractSensor QPointer m_pActionSqdCtrl; /**< show squid control. */ QPointer m_pActionUpdateFiffInfo; /**< Update Fiff Info action. */ + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; signals: //========================================================================================================= /** diff --git a/src/applications/mne_scan/plugins/brainamp/brainamp.cpp b/src/applications/mne_scan/plugins/brainamp/brainamp.cpp index d3c5cc79056..3f4e299b159 100644 --- a/src/applications/mne_scan/plugins/brainamp/brainamp.cpp +++ b/src/applications/mne_scan/plugins/brainamp/brainamp.cpp @@ -84,6 +84,7 @@ BrainAMP::BrainAMP() , m_sRPA("2RD") , m_sNasion("0Z") , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_double(8))) +, m_bProcessOutput(false) { // Create record file option action bar item/button m_pActionSetupProject = new QAction(QIcon(":/images/database.png"), tr("Setup project"), this); diff --git a/src/applications/mne_scan/plugins/brainamp/brainamp.h b/src/applications/mne_scan/plugins/brainamp/brainamp.h index 2e6f6e38557..7604b45e4f3 100644 --- a/src/applications/mne_scan/plugins/brainamp/brainamp.h +++ b/src/applications/mne_scan/plugins/brainamp/brainamp.h @@ -47,6 +47,9 @@ #include #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -232,6 +235,9 @@ protected slots: QAction* m_pActionSetupStimulus; /**< starts stimulus feature. */ QMutex m_mutex; + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/covariance/covariance.cpp b/src/applications/mne_scan/plugins/covariance/covariance.cpp index 63ffd03d172..c1b22534675 100644 --- a/src/applications/mne_scan/plugins/covariance/covariance.cpp +++ b/src/applications/mne_scan/plugins/covariance/covariance.cpp @@ -82,6 +82,7 @@ using namespace Eigen; Covariance::Covariance() : m_iEstimationSamples(2000) , m_pCircularBuffer(CircularBuffer_Matrix_double::SPtr::create(40)) +, m_bProcessOutput(false) { } diff --git a/src/applications/mne_scan/plugins/covariance/covariance.h b/src/applications/mne_scan/plugins/covariance/covariance.h index f268f63c012..0494c59661d 100644 --- a/src/applications/mne_scan/plugins/covariance/covariance.h +++ b/src/applications/mne_scan/plugins/covariance/covariance.h @@ -46,6 +46,7 @@ #include #include +#include //============================================================================================================= // EIGEN INCLUDES diff --git a/src/applications/mne_scan/plugins/hpi/hpi.cpp b/src/applications/mne_scan/plugins/hpi/hpi.cpp index f38706fe5b6..4e6ed735f5d 100644 --- a/src/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/src/applications/mne_scan/plugins/hpi/hpi.cpp @@ -97,6 +97,7 @@ Hpi::Hpi() , m_bUseSSP(false) , m_bUseComp(false) , m_pCircularBuffer(CircularBuffer_Matrix_double::SPtr::create(40)) +, m_bProcessOutput(false) { connect(this, &Hpi::devHeadTransAvailable, this, &Hpi::onDevHeadTransAvailable, Qt::BlockingQueuedConnection); diff --git a/src/applications/mne_scan/plugins/hpi/hpi.h b/src/applications/mne_scan/plugins/hpi/hpi.h index 47f17d26dfb..00ba80075a5 100644 --- a/src/applications/mne_scan/plugins/hpi/hpi.h +++ b/src/applications/mne_scan/plugins/hpi/hpi.h @@ -48,6 +48,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp index 5fc59175815..e31cccefb16 100644 --- a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp +++ b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.cpp @@ -95,6 +95,7 @@ NeuronalConnectivity::NeuronalConnectivity() , m_pCircularBuffer(CircularBuffer::SPtr::create(40)) , m_pRtConnectivity(RtConnectivity::SPtr::create()) , m_pActionShowYourWidget(Q_NULLPTR) +, m_bProcessOutput(false) { AbstractMetric::m_bStorageModeIsActive = true; AbstractMetric::m_iNumberBinStart = 0; diff --git a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h index a175a1904b0..7b3f5ece529 100644 --- a/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h +++ b/src/applications/mne_scan/plugins/neuronalconnectivity/neuronalconnectivity.h @@ -50,6 +50,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp b/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp index e7479cddf89..e1f2471bbc8 100644 --- a/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp +++ b/src/applications/mne_scan/plugins/noisereduction/noisereduction.cpp @@ -93,6 +93,7 @@ NoiseReduction::NoiseReduction() , m_pCircularBuffer(QSharedPointer::create(40)) , m_pNoiseReductionInput(Q_NULLPTR) , m_pNoiseReductionOutput(Q_NULLPTR) +, m_bProcessOutput(false) { if(m_sCurrentSystem == "BabyMEG") { m_iNBaseFctsFirst = 270; diff --git a/src/applications/mne_scan/plugins/noisereduction/noisereduction.h b/src/applications/mne_scan/plugins/noisereduction/noisereduction.h index 0f2276cd527..1c5c2cd23ce 100644 --- a/src/applications/mne_scan/plugins/noisereduction/noisereduction.h +++ b/src/applications/mne_scan/plugins/noisereduction/noisereduction.h @@ -51,6 +51,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp index ce3c1bf44ea..4ecaf16d393 100644 --- a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp +++ b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp @@ -106,6 +106,7 @@ RtcMne::RtcMne() , m_sMethod("dSPM") , m_fMriHeadTrans(QCoreApplication::applicationDirPath() + "/../resources/data/MNE-sample-data/MEG/sample/all-trans.fif") , m_bUpdateMinimumNorm(false) +, m_bProcessOutput(false) { } diff --git a/src/applications/mne_scan/plugins/rtcmne/rtcmne.h b/src/applications/mne_scan/plugins/rtcmne/rtcmne.h index fa3c2cf0faf..289862070d6 100644 --- a/src/applications/mne_scan/plugins/rtcmne/rtcmne.h +++ b/src/applications/mne_scan/plugins/rtcmne/rtcmne.h @@ -51,6 +51,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp b/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp index 1b9c55fd56d..fc3fcd97f15 100644 --- a/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp +++ b/src/applications/mne_scan/plugins/rtfwd/rtfwd.cpp @@ -92,6 +92,7 @@ RtFwd::RtFwd() , m_bDoRecomputation(false) , m_bDoClustering(true) , m_bDoFwdComputation(false) +, m_bProcessOutput(false) { // set init values m_pFwdSettings->solname = QCoreApplication::applicationDirPath() + "/../resources/data/MNE-sample-data/your-solution-fwd.fif"; diff --git a/src/applications/mne_scan/plugins/rtfwd/rtfwd.h b/src/applications/mne_scan/plugins/rtfwd/rtfwd.h index 01ef07fe5ce..c2609569f8b 100644 --- a/src/applications/mne_scan/plugins/rtfwd/rtfwd.h +++ b/src/applications/mne_scan/plugins/rtfwd/rtfwd.h @@ -50,6 +50,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES diff --git a/src/applications/mne_scan/plugins/writetofile/writetofile.cpp b/src/applications/mne_scan/plugins/writetofile/writetofile.cpp index 1ef213112c8..bb7a51fc1b8 100644 --- a/src/applications/mne_scan/plugins/writetofile/writetofile.cpp +++ b/src/applications/mne_scan/plugins/writetofile/writetofile.cpp @@ -78,6 +78,7 @@ WriteToFile::WriteToFile() , m_iSplitCount(0) , m_iRecordingMSeconds(5*60*1000) , m_pCircularBuffer(CircularBuffer_Matrix_double::SPtr(new CircularBuffer_Matrix_double(40))) +, m_bProcessOutput(false) { m_pActionRecordFile = new QAction(QIcon(":/images/record.png"), tr("Start Recording"),this); m_pActionRecordFile->setStatusTip(tr("Start Recording")); diff --git a/src/applications/mne_scan/plugins/writetofile/writetofile.h b/src/applications/mne_scan/plugins/writetofile/writetofile.h index e849fe28230..3246aa0c143 100644 --- a/src/applications/mne_scan/plugins/writetofile/writetofile.h +++ b/src/applications/mne_scan/plugins/writetofile/writetofile.h @@ -47,6 +47,7 @@ #include #include +#include //============================================================================================================= // QT INCLUDES From b19f68246f818b2d46f3ea2d9d788cb5ae54f6d3 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 15:04:45 -0500 Subject: [PATCH 11/13] MAINT: convert rest of sensor plugins --- .../mne_scan/plugins/brainamp/brainamp.cpp | 14 +++++++++----- .../plugins/brainflowboard/brainflowboard.cpp | 17 +++++++++++------ .../plugins/brainflowboard/brainflowboard.h | 7 +++++++ .../mne_scan/plugins/eegosports/eegosports.cpp | 17 +++++++++++------ .../mne_scan/plugins/eegosports/eegosports.h | 6 ++++++ .../mne_scan/plugins/ftbuffer/ftbuffer.cpp | 17 +++++++++++------ .../mne_scan/plugins/ftbuffer/ftbuffer.h | 6 ++++++ .../mne_scan/plugins/gusbamp/gusbamp.cpp | 15 ++++++++++----- .../mne_scan/plugins/gusbamp/gusbamp.h | 6 ++++++ .../mne_scan/plugins/natus/natus.cpp | 17 +++++++++++------ src/applications/mne_scan/plugins/natus/natus.h | 7 +++++++ src/applications/mne_scan/plugins/tmsi/tmsi.cpp | 17 +++++++++++------ src/applications/mne_scan/plugins/tmsi/tmsi.h | 6 ++++++ 13 files changed, 112 insertions(+), 40 deletions(-) diff --git a/src/applications/mne_scan/plugins/brainamp/brainamp.cpp b/src/applications/mne_scan/plugins/brainamp/brainamp.cpp index 3f4e299b159..6071e51eb31 100644 --- a/src/applications/mne_scan/plugins/brainamp/brainamp.cpp +++ b/src/applications/mne_scan/plugins/brainamp/brainamp.cpp @@ -100,7 +100,7 @@ BrainAMP::~BrainAMP() //std::cout << "BrainAMP::~BrainAMP() " << std::endl; //If the program is closed while the sampling is in process - if(this->isRunning()) { + if(m_bProcessOutput) { this->stop(); } } @@ -279,7 +279,8 @@ bool BrainAMP::start() m_iSamplingFreq); if(m_pBrainAMPProducer->isRunning()) { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&BrainAMP::run, this); return true; } else { qWarning() << "BrainAMP::start() - BrainAMPProducer thread could not be started." << endl; @@ -291,8 +292,11 @@ bool BrainAMP::start() bool BrainAMP::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } //Stop the producer thread first m_pBrainAMPProducer->stop(); @@ -373,7 +377,7 @@ void BrainAMP::run() { MatrixXd matData; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { if(m_pBrainAMPProducer->isRunning()) { //pop matrix if(m_pCircularBuffer->pop(matData)) { diff --git a/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.cpp b/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.cpp index 2ad9edad17e..03d46c4f7f3 100644 --- a/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.cpp +++ b/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.cpp @@ -69,6 +69,7 @@ BrainFlowBoard::BrainFlowBoard() , m_sStreamerParams("") , m_uiSamplesPerBlock(100) , m_pFiffInfo(QSharedPointer::create()) +, m_bProcessOutput(false) { m_pShowSettingsAction = new QAction(QIcon(":/images/options.png"), tr("Streaming Settings"),this); m_pShowSettingsAction->setStatusTip(tr("Streaming Settings")); @@ -244,7 +245,8 @@ bool BrainFlowBoard::start() msgBox.exec(); return false; } - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&BrainFlowBoard::run, this); return true; } @@ -256,8 +258,11 @@ bool BrainFlowBoard::stop() if(m_pBoardShim) { m_pBoardShim->stop_stream(); } - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } m_pOutput->measurementData()->clear(); } catch (const BrainFlowException &err) { BoardShim::log_message((int)LogLevels::LEVEL_ERROR, err.what()); @@ -388,12 +393,12 @@ void BrainFlowBoard::run() BrainFlowArray data; QList lSampleBlockBuffer; - while(!isInterruptionRequested()) { - usleep(lSamplingPeriod); + while(m_bProcessOutput) { + std::this_thread::sleep_for(std::chrono::microseconds(lSamplingPeriod)); iSampleIterator = 0; //get samples from device until the complete matrix is filled, i.e. the samples per block size is met - while(iSampleIterator < m_uiSamplesPerBlock && !isInterruptionRequested()) { + while(iSampleIterator < m_uiSamplesPerBlock && m_bProcessOutput) { //Get sample block from device data = m_pBoardShim->get_board_data (); if (data.get_size(1) == 0) { diff --git a/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.h b/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.h index 301fcfba8c3..7e9f7834bc1 100644 --- a/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.h +++ b/src/applications/mne_scan/plugins/brainflowboard/brainflowboard.h @@ -47,6 +47,10 @@ #include +#include +#include + + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -128,6 +132,9 @@ class BRAINFLOWBOARD_EXPORT BrainFlowBoard : public SCSHAREDLIB::AbstractSensor QSharedPointer > m_pOutput; QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } diff --git a/src/applications/mne_scan/plugins/eegosports/eegosports.cpp b/src/applications/mne_scan/plugins/eegosports/eegosports.cpp index 5fabc6d341a..92bcd1d2133 100644 --- a/src/applications/mne_scan/plugins/eegosports/eegosports.cpp +++ b/src/applications/mne_scan/plugins/eegosports/eegosports.cpp @@ -98,6 +98,7 @@ EEGoSports::EEGoSports() , m_sRPA("2RD") , m_sNasion("0Z") , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_double(10))) +, m_bProcessOutput(false) { } @@ -106,7 +107,7 @@ EEGoSports::EEGoSports() EEGoSports::~EEGoSports() { //If the program is closed while the sampling is in process - if(this->isRunning()) { + if(m_bProcessOutput) { this->stop(); } } @@ -564,7 +565,8 @@ bool EEGoSports::start() m_bCheckImpedances); if(m_pEEGoSportsProducer->isRunning()) { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&EEGoSports::run, this);; return true; } else { qWarning() << "[EEGoSports::start] EEGoSports thread could not be started - Either the device is turned off (check your OS device manager) or the driver DLL (EEGO-SDK.dll) is not installed in one of the monitored dll path." << endl; @@ -577,8 +579,11 @@ bool EEGoSports::start() bool EEGoSports::stop() { // Stop this (consumer) thread first - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } //Stop the producer thread m_pEEGoSportsProducer->stop(); @@ -660,7 +665,7 @@ void EEGoSports::onUpdateCardinalPoints(const QString& sLPA, double dLPA, const void EEGoSports::showImpedanceDialog() { // Open Impedance dialog only if no sampling process is active - if(!this->isRunning()) { + if(!m_bProcessOutput) { if(m_pEEGoSportsImpedanceWidget == NULL) { m_pEEGoSportsImpedanceWidget = QSharedPointer(new EEGoSportsImpedanceWidget(this)); } @@ -700,7 +705,7 @@ void EEGoSports::run() { MatrixXd matData; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { if(m_pEEGoSportsProducer->isRunning()) { // Check impedances - send new impedance values to graphic scene if(m_bCheckImpedances) { diff --git a/src/applications/mne_scan/plugins/eegosports/eegosports.h b/src/applications/mne_scan/plugins/eegosports/eegosports.h index 075ab430e4a..5b4cdc7a4c4 100644 --- a/src/applications/mne_scan/plugins/eegosports/eegosports.h +++ b/src/applications/mne_scan/plugins/eegosports/eegosports.h @@ -53,6 +53,9 @@ #include #include +#include +#include + //============================================================================================================= // EIGEN INCLUDES //============================================================================================================= @@ -260,6 +263,9 @@ protected slots: QSharedPointer m_pEEGoSportsProducer; /**< The EEGoSportsProducer.*/ QMutex m_mutex; /**< Holds the threads mutex.*/ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.cpp b/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.cpp index 27373683103..9eeb9e8bf38 100644 --- a/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.cpp +++ b/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.cpp @@ -70,6 +70,7 @@ FtBuffer::FtBuffer() , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_double(10))) , m_sBufferAddress("127.0.0.1") , m_iBufferPort(1972) +, m_bProcessOutput(false) { } @@ -133,7 +134,8 @@ bool FtBuffer::start() qInfo() << "[FtBuffer::start] Producer thread created, sending work command..."; emit workCommand(); - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&FtBuffer::run, this); return true; } @@ -146,14 +148,17 @@ bool FtBuffer::stop() m_bIsConfigured = false; - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } //stops separate producer/client thread first m_pProducerThread.requestInterruption(); int itries = 0; while(m_pProducerThread.isRunning()) { - msleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); if(itries > 10){ break; } @@ -200,12 +205,12 @@ void FtBuffer::run() { MatrixXd matData; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { //qDebug() << "[FtBuffer::run] m_pFiffInfo->dig.size()" << m_pFiffInfo->dig.size(); //pop matrix if(m_pCircularBuffer->pop(matData)) { //emit values - if(!isInterruptionRequested()) { + if(m_bProcessOutput) { m_pRTMSA_BufferOutput->measurementData()->setValue(matData); } } diff --git a/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.h b/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.h index 1fee9b457ef..d196a863833 100644 --- a/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.h +++ b/src/applications/mne_scan/plugins/ftbuffer/ftbuffer.h @@ -55,6 +55,9 @@ #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -253,6 +256,9 @@ class FTBUFFER_EXPORT FtBuffer : public SCSHAREDLIB::AbstractSensor QString m_sBufferAddress; /**< The address used to connect to the buffer if starting without being connected */ int m_iBufferPort; /**< The port used to connect to the buffer if starting without being connected */ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; }//namespace end brace diff --git a/src/applications/mne_scan/plugins/gusbamp/gusbamp.cpp b/src/applications/mne_scan/plugins/gusbamp/gusbamp.cpp index 47eacf012cb..b26b4a88f15 100644 --- a/src/applications/mne_scan/plugins/gusbamp/gusbamp.cpp +++ b/src/applications/mne_scan/plugins/gusbamp/gusbamp.cpp @@ -72,6 +72,7 @@ GUSBAmp::GUSBAmp() , m_iSamplesPerBlock(0) , m_iSampleRate(128) , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_float(8))) +, m_bProcessOutput(false) { m_viChannelsToAcquire = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; @@ -86,7 +87,7 @@ GUSBAmp::GUSBAmp() GUSBAmp::~GUSBAmp() { //If the program is closed while the sampling is in process - if(this->isRunning()){ + if(m_bProcessOutput){ this->stop(); } } @@ -212,7 +213,8 @@ bool GUSBAmp::start() //start the thread for ring buffer if(m_pGUSBAmpProducer->isRunning()) { - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&GUSBAmp::run, this); return true; } else { qWarning() << "Plugin GUSBAmp - ERROR - GUSBAmpProducer thread could not be started - Either the device is turned off (check your OS device manager) or the driver DLL (GUSBAmpSDK.dll / GUSBAmpSDK32bit.dll) is not installed in the system32 / SysWOW64 directory" << endl; @@ -225,8 +227,11 @@ bool GUSBAmp::start() bool GUSBAmp::stop() { // Stop this (consumer) thread first - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } //Stop the producer thread first m_pGUSBAmpProducer->stop(); @@ -271,7 +276,7 @@ void GUSBAmp::run() qint32 size = 0; MatrixXf matValue; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { //pop matrix only if the producer thread is running if(m_pGUSBAmpProducer->isRunning()) { //pop matrix diff --git a/src/applications/mne_scan/plugins/gusbamp/gusbamp.h b/src/applications/mne_scan/plugins/gusbamp/gusbamp.h index 7f749e7408c..2bffd9efcc9 100644 --- a/src/applications/mne_scan/plugins/gusbamp/gusbamp.h +++ b/src/applications/mne_scan/plugins/gusbamp/gusbamp.h @@ -50,6 +50,9 @@ #include "FormFiles/gusbampsetupwidget.h" #include "FormFiles/gusbampsetupprojectwidget.h" +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -211,6 +214,9 @@ class GUSBAMPSHARED_EXPORT GUSBAmp : public SCSHAREDLIB::AbstractSensor std::vector m_viSizeOfSampleMatrix; /**< vector including the size of the two dimensional sample Matrix. */ std::vector m_viChannelsToAcquire; /**< vector of the calling numbers of the channels to be acquired. */ Eigen::RowVectorXd m_cals; + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/natus/natus.cpp b/src/applications/mne_scan/plugins/natus/natus.cpp index 33c058202c7..9aa65e6c299 100644 --- a/src/applications/mne_scan/plugins/natus/natus.cpp +++ b/src/applications/mne_scan/plugins/natus/natus.cpp @@ -75,6 +75,7 @@ Natus::Natus() , m_qStringResourcePath(qApp->applicationDirPath()+"/../resources/mne_scan/plugins/natus/") , m_pRMTSA_Natus(PluginOutputData::create(this, "Natus", "EEG output data")) , m_pFiffInfo(QSharedPointer::create()) +, m_bProcessOutput(false) { m_pRMTSA_Natus->measurementData()->setName(this->getName());//Provide name to auto store widget settings } @@ -84,7 +85,7 @@ Natus::Natus() Natus::~Natus() { //If the program is closed while the sampling is in process - if(this->isRunning()) { + if(m_bProcessOutput) { this->stop(); } } @@ -229,7 +230,8 @@ bool Natus::start() m_pRMTSA_Natus->measurementData()->initFromFiffInfo(m_pFiffInfo); m_pRMTSA_Natus->measurementData()->setMultiArraySize(1); - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&Natus::run, this); // Start the producer m_pNatusProducer = QSharedPointer::create(m_iSamplesPerBlock, m_iNumberChannels); @@ -245,8 +247,11 @@ bool Natus::start() bool Natus::stop() { - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } // Clear all data in the buffer connected to displays and other plugins m_pRMTSA_Natus->measurementData()->clear(); @@ -299,10 +304,10 @@ void Natus::run() { MatrixXd matData; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { if(m_pCircularBuffer->pop(matData)) { //emit values - if(!isInterruptionRequested()) { + if(m_bProcessOutput) { m_pRMTSA_Natus->measurementData()->setValue(matData); } } diff --git a/src/applications/mne_scan/plugins/natus/natus.h b/src/applications/mne_scan/plugins/natus/natus.h index 5621a186e45..30cc33a0270 100644 --- a/src/applications/mne_scan/plugins/natus/natus.h +++ b/src/applications/mne_scan/plugins/natus/natus.h @@ -44,12 +44,16 @@ #include #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= #include #include +#include //============================================================================================================= // EIGEN INCLUDES @@ -181,6 +185,9 @@ class NATUSSHARED_EXPORT Natus : public SCSHAREDLIB::AbstractSensor QSharedPointer > m_pRMTSA_Natus; /**< The RealTimeSampleArray to provide the EEG data.*/ QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE diff --git a/src/applications/mne_scan/plugins/tmsi/tmsi.cpp b/src/applications/mne_scan/plugins/tmsi/tmsi.cpp index e3ff333a2aa..eaeae3f999f 100644 --- a/src/applications/mne_scan/plugins/tmsi/tmsi.cpp +++ b/src/applications/mne_scan/plugins/tmsi/tmsi.cpp @@ -70,6 +70,7 @@ TMSI::TMSI() , m_qStringResourcePath(qApp->applicationDirPath()+"/../resources/mne_scan/plugins/tmsi/") , m_pTMSIProducer(new TMSIProducer(this)) , m_pCircularBuffer(QSharedPointer(new CircularBuffer_Matrix_float(8))) +, m_bProcessOutput(false) { // Create record file option action bar item/button m_pActionSetupProject = new QAction(QIcon(":/images/database.png"), tr("Setup project"), this); @@ -89,7 +90,7 @@ TMSI::TMSI() TMSI::~TMSI() { //If the program is closed while the sampling is in process - if(this->isRunning()) { + if(m_bProcessOutput) { this->stop(); } } @@ -485,7 +486,7 @@ bool TMSI::start() m_bWriteDriverDebugToFile, m_bUseCommonAverage, m_bCheckImpedances); - wait(500); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); if(m_pTMSIProducer->isRunning()) { // Init BCIFeatureWindow for visualization @@ -496,7 +497,8 @@ bool TMSI::start() m_pTmsiManualAnnotationWidget->show(); } - QThread::start(); + m_bProcessOutput = true; + m_OutputProcessingThread = std::thread(&TMSI::run, this); return true; } else { qWarning() << "[TMSI::start] TMSIProducer thread could not be started - Either the device is turned off (check your OS device manager) or the driver DLL (TMSiSDK.dll / TMSiSDK32bit.dll) is not installed in the system32 / SysWOW64 directory" << endl; @@ -512,8 +514,11 @@ bool TMSI::stop() m_pTMSIProducer->stop(); //Wait until this thread (TMSI) is stopped - requestInterruption(); - wait(500); + m_bProcessOutput = false; + + if(m_OutputProcessingThread.joinable()){ + m_OutputProcessingThread.join(); + } // Clear all data in the buffer connected to displays and other plugins m_pRMTSA_TMSI->measurementData()->clear(); @@ -568,7 +573,7 @@ void TMSI::run() qint32 size = 0; MatrixXf matData; - while(!isInterruptionRequested()) { + while(m_bProcessOutput) { // Check impedances - send new impedance values to graphic scene if(m_pTMSIProducer->isRunning() && m_bCheckImpedances) { if(m_pCircularBuffer->pop(matData)) { diff --git a/src/applications/mne_scan/plugins/tmsi/tmsi.h b/src/applications/mne_scan/plugins/tmsi/tmsi.h index e5ddb09db51..4c1fdce616d 100644 --- a/src/applications/mne_scan/plugins/tmsi/tmsi.h +++ b/src/applications/mne_scan/plugins/tmsi/tmsi.h @@ -60,6 +60,9 @@ #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -254,6 +257,9 @@ class TMSISHARED_EXPORT TMSI : public SCSHAREDLIB::AbstractSensor QAction* m_pActionImpedance; /**< shows impedance widget. */ QAction* m_pActionSetupProject; /**< shows setup project dialog. */ + + std::thread m_OutputProcessingThread; + std::atomic_bool m_bProcessOutput; }; } // NAMESPACE From 98699ab3e21ee8b69e7ad0837074866675288ad2 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 26 Jan 2022 15:41:22 -0500 Subject: [PATCH 12/13] MAINT: change missing conditions --- src/applications/mne_scan/plugins/tmsi/tmsi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/mne_scan/plugins/tmsi/tmsi.cpp b/src/applications/mne_scan/plugins/tmsi/tmsi.cpp index eaeae3f999f..fd4e4ba1481 100644 --- a/src/applications/mne_scan/plugins/tmsi/tmsi.cpp +++ b/src/applications/mne_scan/plugins/tmsi/tmsi.cpp @@ -634,7 +634,7 @@ void TMSI::run() void TMSI::showImpedanceDialog() { // Open Impedance dialog only if no sampling process is active - if(!this->isRunning()) { + if(!m_bProcessOutput) { if(m_pTmsiImpedanceWidget == NULL) { m_pTmsiImpedanceWidget = QSharedPointer(new TMSIImpedanceWidget(this)); } From 9a47404e52802d590a862fb8d08d7c1158355368 Mon Sep 17 00:00:00 2001 From: gabrielbmotta Date: Thu, 30 Mar 2023 15:47:16 -0400 Subject: [PATCH 13/13] Fix var setting in fiffsimulator from rebase --- .../mne_scan/plugins/fiffsimulator/fiffsimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp index 31cda8978e8..5e4de948fd8 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulator.cpp @@ -172,7 +172,7 @@ bool FiffSimulator::start() bool FiffSimulator::stop() { // Stop this (consumer) thread first - m_bProcessOutput = false; + m_StopOutputProcessingThread = true; if(m_OutputProcessingThread.joinable()){ m_OutputProcessingThread.join();