diff --git a/assignment-client/src/assets/BakeAssetTask.cpp b/assignment-client/src/assets/BakeAssetTask.cpp index 9a22b065fa..a2fbd5fef4 100644 --- a/assignment-client/src/assets/BakeAssetTask.cpp +++ b/assignment-client/src/assets/BakeAssetTask.cpp @@ -12,11 +12,9 @@ #include "BakeAssetTask.h" #include -#include +#include -#include #include -#include static const int OVEN_STATUS_CODE_SUCCESS { 0 }; static const int OVEN_STATUS_CODE_FAIL { 1 }; @@ -48,7 +46,10 @@ void cleanupTempFiles(QString tempOutputDir, std::vector files) { }; void BakeAssetTask::run() { - _isBaking.store(true); + if (_isBaking.exchange(true)) { + qWarning() << "Tried to start bake asset task while already baking"; + return; + } QString tempOutputDir = PathUtils::generateTemporaryDir(); _outputDir = tempOutputDir; @@ -61,25 +62,27 @@ void BakeAssetTask::run() { "-t", extension, }; - qDebug().noquote() << "Path: " << path << args.join(' '); - QProcess* proc = new QProcess(); + auto _ovenProcess = new QProcess(this); - connect(proc, static_cast(&QProcess::finished), - this, [this, proc, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) { - qDebug() << "Finished process: " << exitCode << exitStatus; - qDebug() << "stdout: " << proc->readAllStandardOutput(); + connect(_ovenProcess, static_cast(&QProcess::finished), + this, [this, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) { + qDebug() << "Baking process finished: " << exitCode << exitStatus; - auto files = _outputDir.entryInfoList(QDir::Files); - QVector outputFiles; - for (auto& file : files) { - qDebug() << "Output file: " << file.absoluteFilePath(); - outputFiles.push_back(file.absoluteFilePath()); - } + if (exitStatus == QProcess::CrashExit) { + _didFinish.store(true); + QString errors = "Fatal error occurred while baking"; + emit bakeFailed(_assetHash, _assetPath, errors); + } else if (exitCode == OVEN_STATUS_CODE_SUCCESS) { + auto files = _outputDir.entryInfoList(QDir::Files); + QVector outputFiles; + for (auto& file : files) { + qDebug() << " Output file: " << file.absoluteFilePath(); + outputFiles.push_back(file.absoluteFilePath()); + } - if (exitCode == OVEN_STATUS_CODE_SUCCESS) { _didFinish.store(true); emit bakeComplete(_assetHash, _assetPath, tempOutputDir, outputFiles); - } else if (exitCode == OVEN_STATUS_CODE_ABORT) { + } else if (exitStatus == QProcess::NormalExit && exitCode == OVEN_STATUS_CODE_ABORT) { _wasAborted.store(true); emit bakeAborted(_assetHash, _assetPath); } else { @@ -92,81 +95,22 @@ void BakeAssetTask::run() { errors = errorFile.readAll(); errorFile.close(); } else { - errors = "Unknown error occurred"; + errors = "Unknown error occurred while baking"; } } emit bakeFailed(_assetHash, _assetPath, errors); } }); - connect(proc, &QProcess::errorOccurred, this, []() { - qDebug() << "Error occurred :("; - }); - connect(proc, &QProcess::started, this, []() { - qDebug() << "Process started"; - }); - proc->start(path, args, QIODevice::ReadOnly); - proc->waitForStarted(); - proc->waitForFinished(); - - return; - - qRegisterMetaType >("QVector"); - TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); }; - - if (_assetPath.endsWith(".fbx")) { - _baker = std::unique_ptr { - new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir) - }; - } else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) { - _baker = std::unique_ptr{ - new JSBaker(QUrl("file:///" + _filePath), tempOutputDir) - }; - } else { - _baker = std::unique_ptr { - new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE, - tempOutputDir) - }; - } - - QEventLoop loop; - connect(_baker.get(), &Baker::finished, &loop, &QEventLoop::quit); - connect(_baker.get(), &Baker::aborted, &loop, &QEventLoop::quit); - QMetaObject::invokeMethod(_baker.get(), "bake", Qt::QueuedConnection); - loop.exec(); - - if (_baker->wasAborted()) { - qDebug() << "Aborted baking: " << _assetHash << _assetPath; - - _wasAborted.store(true); - - cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); - - emit bakeAborted(_assetHash, _assetPath); - } else if (_baker->hasErrors()) { - qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors(); - - auto errors = _baker->getErrors().join('\n'); // Join error list into a single string for convenience - - _didFinish.store(true); - - cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); - - emit bakeFailed(_assetHash, _assetPath, errors); - } else { - auto vectorOutputFiles = QVector::fromStdVector(_baker->getOutputFiles()); - - qDebug() << "Finished baking: " << _assetHash << _assetPath << vectorOutputFiles; - - _didFinish.store(true); - - emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles); - } + qDebug() << "Starting oven for " << _assetPath; + _ovenProcess->start(path, args, QIODevice::ReadOnly); + _ovenProcess->waitForStarted(); + _ovenProcess->waitForFinished(); } void BakeAssetTask::abort() { - if (_baker) { - _baker->abort(); + if (!_wasAborted.exchange(true)) { + _ovenProcess.terminate(); } } diff --git a/assignment-client/src/assets/BakeAssetTask.h b/assignment-client/src/assets/BakeAssetTask.h index 48461bc1b3..970ea83317 100644 --- a/assignment-client/src/assets/BakeAssetTask.h +++ b/assignment-client/src/assets/BakeAssetTask.h @@ -18,9 +18,9 @@ #include #include #include +#include #include -#include class BakeAssetTask : public QObject, public QRunnable { Q_OBJECT @@ -46,7 +46,7 @@ private: AssetPath _assetPath; QString _filePath; QDir _outputDir; - std::unique_ptr _baker; + QProcess _ovenProcess { nullptr }; std::atomic _wasAborted { false }; std::atomic _didFinish { false }; }; diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index acf053aaed..2e1b526463 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -67,7 +67,7 @@ QString PathUtils::generateTemporaryDir() { for (auto i = 0; i < 64; ++i) { auto now = std::chrono::system_clock::now().time_since_epoch().count(); auto dirName = TEMP_DIR_FORMAT.arg(appName).arg(qApp->applicationPid()).arg(now); - QDir tempDir = rootTempDir.filePath(appName + "-" + QString::number(now)); + QDir tempDir = rootTempDir.filePath(dirName); if (tempDir.mkpath(".")) { return tempDir.absolutePath(); } @@ -83,32 +83,27 @@ int PathUtils::removeTemporaryDirs(QString appName) { auto dirName = TEMP_DIR_FORMAT.arg(appName).arg("*").arg("*"); qDebug() << "Dirname format is: " << dirName; + auto pid = qApp->applicationPid(); QDir rootTempDir = QDir::tempPath(); - qDebug() << "Temp dir is: " << rootTempDir; auto dirs = rootTempDir.entryInfoList({ dirName }, QDir::Dirs); int removed = 0; for (auto& dir : dirs) { auto dirName = dir.fileName(); auto absoluteDirPath = QDir(dir.absoluteFilePath()); - qDebug() << " Deleting: " << dirName << absoluteDirPath; QRegularExpression re { "^" + QRegularExpression::escape(appName) + "\\-(?\\d+)\\-(?\\d+)$" }; auto match = re.match(dirName); if (match.hasMatch()) { - qDebug() << " Got match"; auto pid = match.capturedRef("pid").toLongLong(); auto timestamp = match.capturedRef("timestamp"); - qDebug() << " Is " << pid << " running?" << processIsRunning(pid); if (!processIsRunning(pid)) { - qDebug() << " Removing: " << absoluteDirPath; + qDebug() << " Removing old temporary directory: " << absoluteDirPath; absoluteDirPath.removeRecursively(); removed++; } else { qDebug() << " Not removing (process is running): " << dir.absoluteDir(); } - } else { - qDebug() << " NO MATCH"; } } diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 294546d1f0..7ca915b0d0 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -47,6 +47,7 @@ extern "C" FILE * __cdecl __iob_func(void) { #if defined(Q_OS_LINUX) || defined(__APPLE__) #include +#include #endif #include @@ -1094,7 +1095,12 @@ bool processIsRunning(int64_t pid) { } return false; #elif defined(Q_OS_LINUX) || defined(__APPLE__) - return kill(pid, 0) != ESRCH; + if (kill(pid, 0) == -1) { + return errno != ESRCH; + } + return true; +#else + static_assert(false); #endif }