[Worker] In order to make background validation (worker) stoppable, using an "atomic bool stop flag"

Originally Ref T145, Ref T647
This commit is contained in:
Klaus Basan
2020-03-06 18:54:05 +01:00
committed by Mat Sutcliffe
parent 9bcc16b94e
commit 7f6e3e5378
9 changed files with 36 additions and 30 deletions

View File

@@ -13,6 +13,7 @@
#include <QPushButton> #include <QPushButton>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QPointer> #include <QPointer>
#include <atomic>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
@@ -63,7 +64,7 @@ namespace BlackGui
CAircraftModelList invalid; CAircraftModelList invalid;
const bool ignoreEmpty = false; const bool ignoreEmpty = false;
const int maxFailedFiles = 25; const int maxFailedFiles = 25;
bool wasStopped = false; std::atomic_bool wasStopped { false };
const CStatusMessageList msgs = CAircraftModelUtilities::validateModelFiles(m_simulator, m_models, valid, invalid, ignoreEmpty, maxFailedFiles, wasStopped, m_simulatorDir); const CStatusMessageList msgs = CAircraftModelUtilities::validateModelFiles(m_simulator, m_models, valid, invalid, ignoreEmpty, maxFailedFiles, wasStopped, m_simulatorDir);
ui->comp_StatusMessage->clear(); ui->comp_StatusMessage->clear();
ui->comp_StatusMessage->setNoSorting(); // we use the pre-sorted list ui->comp_StatusMessage->setNoSorting(); // we use the pre-sorted list

View File

@@ -1527,7 +1527,7 @@ namespace BlackMisc
return msgs; return msgs;
} }
CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped, const QString &simRootDirectory, bool alreadySortedByFn) const CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simRootDirectory, bool alreadySortedByFn) const
{ {
wasStopped = false; wasStopped = false;
@@ -1575,7 +1575,7 @@ namespace BlackMisc
if (workingFiles.contains(fn) || model.hasExistingCorrespondingFile()) if (workingFiles.contains(fn) || model.hasExistingCorrespondingFile())
{ {
if (!simRootDirectory.isEmpty() && !fn.contains(simRootDir)) if (!simRootDirectory.isEmpty() && !fn.contains(simRootDir))
{ {
// check if in root directory // check if in root directory
msgs.push_back(CStatusMessage(this).validationError(u"'%1', not in root directory '%2', '%3' skipped") << model.getModelStringAndDbKey() << simRootDir << model.getFileName()); msgs.push_back(CStatusMessage(this).validationError(u"'%1', not in root directory '%2', '%3' skipped") << model.getModelStringAndDbKey() << simRootDir << model.getFileName());
@@ -1663,17 +1663,17 @@ namespace BlackMisc
// convert // convert
{ {
CJsonScope scope("aircraftIcaos"); CJsonScope scope("aircraftIcaos");
Q_UNUSED(scope); Q_UNUSED(scope)
helper.getTable<CAircraftIcaoCode>().convertFromJson(aircraftIcaos.toObject()); helper.getTable<CAircraftIcaoCode>().convertFromJson(aircraftIcaos.toObject());
} }
{ {
CJsonScope scope("liveries"); CJsonScope scope("liveries");
Q_UNUSED(scope); Q_UNUSED(scope)
helper.getTable<CLivery>().convertFromJson(liveries.toObject()); helper.getTable<CLivery>().convertFromJson(liveries.toObject());
} }
{ {
CJsonScope scope("distributors"); CJsonScope scope("distributors");
Q_UNUSED(scope); Q_UNUSED(scope)
helper.getTable<CDistributor>().convertFromJson(distributors.toObject()); helper.getTable<CDistributor>().convertFromJson(distributors.toObject());
} }
@@ -1681,7 +1681,7 @@ namespace BlackMisc
for (auto i = array.begin(); i != array.end(); ++i) for (auto i = array.begin(); i != array.end(); ++i)
{ {
CJsonScope scope("containerbase", index++); CJsonScope scope("containerbase", index++);
Q_UNUSED(scope); Q_UNUSED(scope)
CAircraftModel value; CAircraftModel value;
value.convertFromMemoizedJson(i->toObject(), helper); value.convertFromMemoizedJson(i->toObject(), helper);
this->push_back(value); this->push_back(value);

View File

@@ -36,6 +36,7 @@
#include <Qt> #include <Qt>
#include <QHash> #include <QHash>
#include <QMap> #include <QMap>
#include <atomic>
namespace BlackMisc namespace BlackMisc
{ {
@@ -509,7 +510,7 @@ namespace BlackMisc
CStatusMessageList validateDistributors(const CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const; CStatusMessageList validateDistributors(const CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const;
//! Validate files (file exists etc.) //! Validate files (file exists etc.)
CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped, const QString &simRootDirectory, bool alreadySortedByFn = false) const; CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simRootDirectory, bool alreadySortedByFn = false) const;
//! To compact JSON format //! To compact JSON format
QJsonObject toMemoizedJson() const; QJsonObject toMemoizedJson() const;

View File

@@ -140,7 +140,7 @@ namespace BlackMisc
return ok ? dir.absoluteFilePath(fn) : ""; return ok ? dir.absoluteFilePath(fn) : "";
} }
CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &wasStopped, const QString &simulatorDir) CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir)
{ {
// some generic tests // some generic tests
CStatusMessageList msgs; CStatusMessageList msgs;

View File

@@ -11,6 +11,7 @@
#ifndef BLACKMISC_SIMULATION_AIRCRAFTMODELUTILS_H #ifndef BLACKMISC_SIMULATION_AIRCRAFTMODELUTILS_H
#define BLACKMISC_SIMULATION_AIRCRAFTMODELUTILS_H #define BLACKMISC_SIMULATION_AIRCRAFTMODELUTILS_H
#include <atomic>
#include "blackmisc/blackmiscexport.h" #include "blackmisc/blackmiscexport.h"
#include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/aircraftmodellist.h"
@@ -36,7 +37,7 @@ namespace BlackMisc
static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir); static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir);
//! Validate aircraft.cfg entries //! Validate aircraft.cfg entries
static CStatusMessageList validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &wasStopped, const QString &simulatorDir); static CStatusMessageList validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir);
}; };
} //namespace } //namespace
} // namespace } // namespace

View File

@@ -104,9 +104,10 @@ namespace BlackMisc
return true; return true;
} }
unsigned long CBackgroundValidation::waitTimeoutMs() const void CBackgroundValidation::beforeQuit() noexcept
{ {
return 0; m_wasStopped = true; // stop in utility functions
m_updateTimer.stop();
} }
void CBackgroundValidation::doWork() void CBackgroundValidation::doWork()
@@ -119,11 +120,11 @@ namespace BlackMisc
CAircraftModelList valid; CAircraftModelList valid;
CAircraftModelList invalid; CAircraftModelList invalid;
CStatusMessageList msgs; CStatusMessageList msgs;
bool wasStopped = false;
bool validated = false; bool validated = false;
bool onlyErrorsAndWarnings = false; bool onlyErrorsAndWarnings = false;
const CSimulatorInfo simulator = this->getCurrentSimulator(); const CSimulatorInfo simulator = this->getCurrentSimulator();
const qint64 started = QDateTime::currentMSecsSinceEpoch(); const qint64 started = QDateTime::currentMSecsSinceEpoch();
m_wasStopped = false;
do do
{ {
@@ -144,7 +145,7 @@ namespace BlackMisc
} }
else else
{ {
msgs = CAircraftModelUtilities::validateModelFiles(simulator, models, valid, invalid, false, 25, wasStopped, m_simDirectory); msgs = CAircraftModelUtilities::validateModelFiles(simulator, models, valid, invalid, false, 25, m_wasStopped, m_simDirectory);
} }
const qint64 deltaTimeMs = now - started; const qint64 deltaTimeMs = now - started;
@@ -155,7 +156,7 @@ namespace BlackMisc
QWriteLocker l(&m_lock); QWriteLocker l(&m_lock);
m_lastResultValid = valid; m_lastResultValid = valid;
m_lastResultInvalid = invalid; m_lastResultInvalid = invalid;
m_lastResultWasStopped = wasStopped; m_lastResultWasStopped = m_wasStopped;
m_lastResultSimulator = simulator; m_lastResultSimulator = simulator;
m_lastResultMsgs = msgs; m_lastResultMsgs = msgs;
m_checkedSimulatorMsgs.insert(simulator, msgs); m_checkedSimulatorMsgs.insert(simulator, msgs);
@@ -178,7 +179,7 @@ namespace BlackMisc
if (validated) if (validated)
{ {
const bool e = !onlyErrorsAndWarnings || (!invalid.isEmpty() || msgs.hasWarningOrErrorMessages()); const bool e = !onlyErrorsAndWarnings || (!invalid.isEmpty() || msgs.hasWarningOrErrorMessages());
if (e || !isTimerBased) { emit this->validated(simulator, valid, invalid, wasStopped, msgs); } if (e || !isTimerBased) { emit this->validated(simulator, valid, invalid, m_wasStopped, msgs); }
} }
} }
} // ns } // ns

View File

@@ -76,14 +76,15 @@ namespace BlackMisc
void validated(const CSimulatorInfo &simulator, const CAircraftModelList &validModels, const CAircraftModelList &invalidModels, bool stopped, const CStatusMessageList &msgs); void validated(const CSimulatorInfo &simulator, const CAircraftModelList &validModels, const CAircraftModelList &invalidModels, bool stopped, const CStatusMessageList &msgs);
protected: protected:
//! \copydoc CContinuousWorker::waitTimeoutMs //! \copydoc CContinuousWorker::beforeQuit
virtual unsigned long waitTimeoutMs() const override; virtual void beforeQuit() noexcept override;
private: private:
mutable QReadWriteLock m_lock; //!< lock snapshot mutable QReadWriteLock m_lock; //!< lock snapshot
std::atomic_bool m_inWork { false }; //!< indicates a running update std::atomic_bool m_inWork { false }; //!< indicates a running update
CSimulatorInfo m_simulator; //!< simulator std::atomic_bool m_wasStopped { false }; //!< has been stopped or should be stopped
QString m_simDirectory; //!< corresponding sim directory CSimulatorInfo m_simulator; //!< simulator
QString m_simDirectory; //!< corresponding sim directory
// last result values, mostly needed when running in the distributed swift system and we want to get the values // last result values, mostly needed when running in the distributed swift system and we want to get the values
CAircraftModelList m_lastResultValid; CAircraftModelList m_lastResultValid;

View File

@@ -639,7 +639,7 @@ namespace BlackMisc
return paths; return paths;
} }
CStatusMessageList CFsCommonUtil::validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped) CStatusMessageList CFsCommonUtil::validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped)
{ {
CStatusMessage m; CStatusMessage m;
CAircraftModelList sorted(models); CAircraftModelList sorted(models);
@@ -703,14 +703,14 @@ namespace BlackMisc
return msgs; return msgs;
} }
CStatusMessageList CFsCommonUtil::validateP3DSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped, const QString &simulatorDir) CStatusMessageList CFsCommonUtil::validateP3DSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir)
{ {
const QString simObjectsDir = simulatorDir.isEmpty() ? CFsCommonUtil::p3dSimObjectsDir() : CFsCommonUtil::p3dSimObjectsDirFromSimDir(simulatorDir); const QString simObjectsDir = simulatorDir.isEmpty() ? CFsCommonUtil::p3dSimObjectsDir() : CFsCommonUtil::p3dSimObjectsDirFromSimDir(simulatorDir);
const QStringList simObjectPaths = CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(simObjectsDir, "v4"); const QStringList simObjectPaths = CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(simObjectsDir, "v4");
return CFsCommonUtil::validateSimObjectsPath(QSet<QString>(simObjectPaths.begin(), simObjectPaths.end()), models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, wasStopped); return CFsCommonUtil::validateSimObjectsPath(QSet<QString>(simObjectPaths.begin(), simObjectPaths.end()), models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, wasStopped);
} }
CStatusMessageList CFsCommonUtil::validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir) CStatusMessageList CFsCommonUtil::validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &stopped, const QString &simulatorDir)
{ {
Q_UNUSED(simulatorDir) Q_UNUSED(simulatorDir)
const QStringList simObjectPaths = CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(); const QStringList simObjectPaths = CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths();
@@ -726,7 +726,7 @@ namespace BlackMisc
CStatusMessageList CFsCommonUtil::validateSimObjectsPath( CStatusMessageList CFsCommonUtil::validateSimObjectsPath(
const QSet<QString> &simObjectDirs, const CAircraftModelList &models, const QSet<QString> &simObjectDirs, const CAircraftModelList &models,
CAircraftModelList &validModels, CAircraftModelList &invalidModels, CAircraftModelList &validModels, CAircraftModelList &invalidModels,
bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped) bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &stopped)
{ {
CStatusMessageList msgs; CStatusMessageList msgs;
if (simObjectDirs.isEmpty()) if (simObjectDirs.isEmpty())

View File

@@ -15,6 +15,7 @@
#include "blackmisc/logcategorylist.h" #include "blackmisc/logcategorylist.h"
#include "blackmisc/blackmiscexport.h" #include "blackmisc/blackmiscexport.h"
#include <atomic>
#include <QSet> #include <QSet>
#include <QStringList> #include <QStringList>
@@ -139,15 +140,15 @@ namespace BlackMisc
//! Validate aircraft.cfg entries (sometimes also sim.cfg) //! Validate aircraft.cfg entries (sometimes also sim.cfg)
//! \remark only for FSX/P3D/FS9 models //! \remark only for FSX/P3D/FS9 models
static CStatusMessageList validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped); static CStatusMessageList validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped);
//! Validate if known SimObjects path are used //! Validate if known SimObjects path are used
//! \remark only for P3D //! \remark only for P3D
static CStatusMessageList validateP3DSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped, const QString &simulatorDir); static CStatusMessageList validateP3DSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir);
//! Validate if known SimObjects path are used //! Validate if known SimObjects path are used
//! \remark only for FSX //! \remark only for FSX
static CStatusMessageList validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &wasStopped, const QString &simulatorDir); static CStatusMessageList validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir);
//! .air file filter //! .air file filter
static const QString airFileFilter(); static const QString airFileFilter();
@@ -159,7 +160,7 @@ namespace BlackMisc
//! Validate if known SimObjects path are used //! Validate if known SimObjects path are used
//! \remark only for P3D/FSX //! \remark only for P3D/FSX
static CStatusMessageList validateSimObjectsPath(const QSet<QString> &simObjectDirs, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped); static CStatusMessageList validateSimObjectsPath(const QSet<QString> &simObjectDirs, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &stopped);
//! Log the reading of config files //! Log the reading of config files
static bool logConfigPathReading(); static bool logConfigPathReading();