From 2c1055cc2e4b2cf63395c10e14d9821bc763bc80 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 27 Aug 2018 18:48:02 +0200 Subject: [PATCH] Ref T312, fixed thread safety of listeners start/stop/check --- src/blackcore/simulator.cpp | 27 ++++++++++++++++++- src/blackcore/simulator.h | 6 ++++- .../simulator/emulated/simulatoremulated.cpp | 4 +-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/blackcore/simulator.cpp b/src/blackcore/simulator.cpp index 552bf9c41..0c080dce9 100644 --- a/src/blackcore/simulator.cpp +++ b/src/blackcore/simulator.cpp @@ -12,6 +12,7 @@ #include "blackcore/webdataservices.h" #include "blackcore/application.h" #include "blackmisc/directoryutils.h" +#include "blackmisc/threadutils.h" #include "blackmisc/logmessage.h" #include @@ -1135,6 +1136,14 @@ namespace BlackCore void ISimulatorListener::start() { if (m_isRunning) { return; } + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + // call in correct thread + QPointer myself(this); + QTimer::singleShot(0, this, [ = ] { if (myself) { this->start(); }}); + return; + } + m_isRunning = true; this->startImpl(); } @@ -1142,13 +1151,29 @@ namespace BlackCore void ISimulatorListener::stop() { if (!m_isRunning) { return; } + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + // call in correct thread + QPointer myself(this); + QTimer::singleShot(0, this, [ = ] { if (myself) { this->stop(); }}); + return; + } + this->stopImpl(); m_isRunning = false; } void ISimulatorListener::check() { - if (!m_isRunning) { return; } + if (m_isRunning) { return; } + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + // call in correct thread + QPointer myself(this); + QTimer::singleShot(0, this, [ = ] { if (myself) { this->check(); }}); + return; + } + this->checkImpl(); } } // namespace diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index d1ad990d0..4fc269262 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -43,6 +43,7 @@ #include #include #include +#include namespace BlackMisc { @@ -586,12 +587,15 @@ namespace BlackCore public slots: //! Start listening for the simulator to start. + //! \threadsafe void start(); //! Stops listening. + //! \threadsafe void stop(); //! Check simulator availability + //! \threadsafe void check(); signals: @@ -617,7 +621,7 @@ namespace BlackCore private: BlackMisc::Simulation::CSimulatorPluginInfo m_info; - bool m_isRunning = false; + std::atomic_bool m_isRunning { false }; }; //! Factory pattern class to create instances of ISimulator diff --git a/src/plugins/simulator/emulated/simulatoremulated.cpp b/src/plugins/simulator/emulated/simulatoremulated.cpp index 35a297328..a54abd9fa 100644 --- a/src/plugins/simulator/emulated/simulatoremulated.cpp +++ b/src/plugins/simulator/emulated/simulatoremulated.cpp @@ -443,10 +443,10 @@ namespace BlackSimPlugin void CSimulatorEmulatedListener::startImpl() { if (this->isShuttingDown()) { return; } - const QPointer guard(this); + const QPointer myself(this); QTimer::singleShot(2000, this, [ = ] { - if (!guard) { return; } + if (!myself) { return; } Q_ASSERT_X(this->getPluginInfo().isValid(), Q_FUNC_INFO, "Invalid plugin"); emit this->simulatorStarted(this->getPluginInfo()); });