Make BakeAssetTask::abort thread-safe

This commit is contained in:
Ryan Huffman 2018-02-23 10:57:35 -08:00
parent 85bd0442a7
commit c368c84f59
3 changed files with 22 additions and 4 deletions

View file

@ -289,6 +289,7 @@ void AssetServer::aboutToFinish() {
if (pendingRunnable) { if (pendingRunnable) {
it = _pendingBakes.erase(it); it = _pendingBakes.erase(it);
} else { } else {
qDebug() << "Aborting bake for" << it.key();
it.value()->abort(); it.value()->abort();
++it; ++it;
} }
@ -1387,6 +1388,8 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
} }
void AssetServer::handleAbortedBake(QString originalAssetHash, QString assetPath) { 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 // for an aborted bake we don't do anything but remove the BakeAssetTask from our pending bakes
_pendingBakes.remove(originalAssetHash); _pendingBakes.remove(originalAssetHash);
} }

View file

@ -69,8 +69,10 @@ void BakeAssetTask::run() {
_ovenProcess.reset(new QProcess()); _ovenProcess.reset(new QProcess());
QEventLoop loop;
connect(_ovenProcess.get(), static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), connect(_ovenProcess.get(), static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&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; qDebug() << "Baking process finished: " << exitCode << exitStatus;
if (exitStatus == QProcess::CrashExit) { if (exitStatus == QProcess::CrashExit) {
@ -108,6 +110,7 @@ void BakeAssetTask::run() {
emit bakeFailed(_assetHash, _assetPath, errors); emit bakeFailed(_assetHash, _assetPath, errors);
} }
loop.quit();
}); });
qDebug() << "Starting oven for " << _assetPath; qDebug() << "Starting oven for " << _assetPath;
@ -117,11 +120,21 @@ void BakeAssetTask::run() {
emit bakeFailed(_assetHash, _assetPath, errors); emit bakeFailed(_assetHash, _assetPath, errors);
return; return;
} }
_ovenProcess->waitForFinished();
_isBaking = true;
loop.exec();
} }
void BakeAssetTask::abort() { 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(); _ovenProcess->terminate();
} }
} }

View file

@ -27,12 +27,14 @@ class BakeAssetTask : public QObject, public QRunnable {
public: public:
BakeAssetTask(const AssetUtils::AssetHash& assetHash, const AssetUtils::AssetPath& assetPath, const QString& filePath); BakeAssetTask(const AssetUtils::AssetHash& assetHash, const AssetUtils::AssetPath& assetPath, const QString& filePath);
// Thread-safe inspection methods
bool isBaking() { return _isBaking.load(); } bool isBaking() { return _isBaking.load(); }
bool wasAborted() const { return _wasAborted.load(); }
void run() override; void run() override;
public slots:
void abort(); void abort();
bool wasAborted() const { return _wasAborted.load(); }
signals: signals:
void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector<QString> outputFiles); void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector<QString> outputFiles);