From c368c84f59d18e32b8b4c4febd75b0f1a88e2e00 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 23 Feb 2018 10:57:35 -0800 Subject: [PATCH] Make BakeAssetTask::abort thread-safe --- assignment-client/src/assets/AssetServer.cpp | 3 +++ .../src/assets/BakeAssetTask.cpp | 19 ++++++++++++++++--- assignment-client/src/assets/BakeAssetTask.h | 4 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index f600f5edc2..c69ef2d9cc 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -289,6 +289,7 @@ void AssetServer::aboutToFinish() { if (pendingRunnable) { it = _pendingBakes.erase(it); } else { + qDebug() << "Aborting bake for" << it.key(); it.value()->abort(); ++it; } @@ -1387,6 +1388,8 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina } void AssetServer::handleAbortedBake(QString originalAssetHash, QString assetPath) { + qDebug() << "Aborted bake:" << originalAssetHash; + // for an aborted bake we don't do anything but remove the BakeAssetTask from our pending bakes _pendingBakes.remove(originalAssetHash); } diff --git a/assignment-client/src/assets/BakeAssetTask.cpp b/assignment-client/src/assets/BakeAssetTask.cpp index 5b9add7467..ecb4ede5d8 100644 --- a/assignment-client/src/assets/BakeAssetTask.cpp +++ b/assignment-client/src/assets/BakeAssetTask.cpp @@ -69,8 +69,10 @@ void BakeAssetTask::run() { _ovenProcess.reset(new QProcess()); + QEventLoop loop; + connect(_ovenProcess.get(), static_cast(&QProcess::finished), - this, [this, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) { + this, [&loop, this, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) { qDebug() << "Baking process finished: " << exitCode << exitStatus; if (exitStatus == QProcess::CrashExit) { @@ -108,6 +110,7 @@ void BakeAssetTask::run() { emit bakeFailed(_assetHash, _assetPath, errors); } + loop.quit(); }); qDebug() << "Starting oven for " << _assetPath; @@ -117,11 +120,21 @@ void BakeAssetTask::run() { emit bakeFailed(_assetHash, _assetPath, errors); return; } - _ovenProcess->waitForFinished(); + + _isBaking = true; + + loop.exec(); } void BakeAssetTask::abort() { - if (!_wasAborted.exchange(true)) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "abort"); + return; + } + qDebug() << "Aborting BakeAssetTask for" << _assetHash; + if (_ovenProcess->state() != QProcess::NotRunning) { + qDebug() << "Teminating oven process for" << _assetHash; + _wasAborted = true; _ovenProcess->terminate(); } } diff --git a/assignment-client/src/assets/BakeAssetTask.h b/assignment-client/src/assets/BakeAssetTask.h index 7b003fa1bd..24b070d08a 100644 --- a/assignment-client/src/assets/BakeAssetTask.h +++ b/assignment-client/src/assets/BakeAssetTask.h @@ -27,12 +27,14 @@ class BakeAssetTask : public QObject, public QRunnable { public: BakeAssetTask(const AssetUtils::AssetHash& assetHash, const AssetUtils::AssetPath& assetPath, const QString& filePath); + // Thread-safe inspection methods bool isBaking() { return _isBaking.load(); } + bool wasAborted() const { return _wasAborted.load(); } void run() override; +public slots: void abort(); - bool wasAborted() const { return _wasAborted.load(); } signals: void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector outputFiles);