Ref T312, fixed thread safety of listeners start/stop/check

This commit is contained in:
Klaus Basan
2018-08-27 18:48:02 +02:00
parent 0b0a7783a0
commit 2c1055cc2e
3 changed files with 33 additions and 4 deletions

View File

@@ -12,6 +12,7 @@
#include "blackcore/webdataservices.h" #include "blackcore/webdataservices.h"
#include "blackcore/application.h" #include "blackcore/application.h"
#include "blackmisc/directoryutils.h" #include "blackmisc/directoryutils.h"
#include "blackmisc/threadutils.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include <QFlag> #include <QFlag>
@@ -1135,6 +1136,14 @@ namespace BlackCore
void ISimulatorListener::start() void ISimulatorListener::start()
{ {
if (m_isRunning) { return; } if (m_isRunning) { return; }
if (!CThreadUtils::isCurrentThreadObjectThread(this))
{
// call in correct thread
QPointer<ISimulatorListener> myself(this);
QTimer::singleShot(0, this, [ = ] { if (myself) { this->start(); }});
return;
}
m_isRunning = true; m_isRunning = true;
this->startImpl(); this->startImpl();
} }
@@ -1142,13 +1151,29 @@ namespace BlackCore
void ISimulatorListener::stop() void ISimulatorListener::stop()
{ {
if (!m_isRunning) { return; } if (!m_isRunning) { return; }
if (!CThreadUtils::isCurrentThreadObjectThread(this))
{
// call in correct thread
QPointer<ISimulatorListener> myself(this);
QTimer::singleShot(0, this, [ = ] { if (myself) { this->stop(); }});
return;
}
this->stopImpl(); this->stopImpl();
m_isRunning = false; m_isRunning = false;
} }
void ISimulatorListener::check() void ISimulatorListener::check()
{ {
if (!m_isRunning) { return; } if (m_isRunning) { return; }
if (!CThreadUtils::isCurrentThreadObjectThread(this))
{
// call in correct thread
QPointer<ISimulatorListener> myself(this);
QTimer::singleShot(0, this, [ = ] { if (myself) { this->check(); }});
return;
}
this->checkImpl(); this->checkImpl();
} }
} // namespace } // namespace

View File

@@ -43,6 +43,7 @@
#include <QFlags> #include <QFlags>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <atomic>
namespace BlackMisc namespace BlackMisc
{ {
@@ -586,12 +587,15 @@ namespace BlackCore
public slots: public slots:
//! Start listening for the simulator to start. //! Start listening for the simulator to start.
//! \threadsafe
void start(); void start();
//! Stops listening. //! Stops listening.
//! \threadsafe
void stop(); void stop();
//! Check simulator availability //! Check simulator availability
//! \threadsafe
void check(); void check();
signals: signals:
@@ -617,7 +621,7 @@ namespace BlackCore
private: private:
BlackMisc::Simulation::CSimulatorPluginInfo m_info; BlackMisc::Simulation::CSimulatorPluginInfo m_info;
bool m_isRunning = false; std::atomic_bool m_isRunning { false };
}; };
//! Factory pattern class to create instances of ISimulator //! Factory pattern class to create instances of ISimulator

View File

@@ -443,10 +443,10 @@ namespace BlackSimPlugin
void CSimulatorEmulatedListener::startImpl() void CSimulatorEmulatedListener::startImpl()
{ {
if (this->isShuttingDown()) { return; } if (this->isShuttingDown()) { return; }
const QPointer<CSimulatorEmulatedListener> guard(this); const QPointer<CSimulatorEmulatedListener> myself(this);
QTimer::singleShot(2000, this, [ = ] QTimer::singleShot(2000, this, [ = ]
{ {
if (!guard) { return; } if (!myself) { return; }
Q_ASSERT_X(this->getPluginInfo().isValid(), Q_FUNC_INFO, "Invalid plugin"); Q_ASSERT_X(this->getPluginInfo().isValid(), Q_FUNC_INFO, "Invalid plugin");
emit this->simulatorStarted(this->getPluginInfo()); emit this->simulatorStarted(this->getPluginInfo());
}); });