From 3c6316df8244ed0958e08337f3eaeacd9573a173 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Thu, 9 May 2019 22:18:44 +0200 Subject: [PATCH] Some code refactoring in the "startup" threads. --- src/thread_avisynth.cpp | 64 ++++++++++++++---------------------------- src/thread_avisynth.h | 10 ++----- src/thread_binaries.cpp | 67 +++++++++++++------------------------------- src/thread_binaries.h | 19 ++++--------- src/thread_startup.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++-- src/thread_startup.h | 24 ++++++++++++++++ src/thread_vapoursynth.cpp | 60 ++++++++++++---------------------------- src/thread_vapoursynth.h | 21 ++++---------- src/version.h | 2 +- 9 files changed, 162 insertions(+), 174 deletions(-) diff --git a/src/thread_avisynth.cpp b/src/thread_avisynth.cpp index 129fb3d..97520a5 100644 --- a/src/thread_avisynth.cpp +++ b/src/thread_avisynth.cpp @@ -22,7 +22,6 @@ #include "thread_avisynth.h" //Qt -#include #include #include #include @@ -43,11 +42,13 @@ static const bool ENABLE_PORTABLE_AVS = true; QMutex AvisynthCheckThread::m_avsLock; QScopedPointer AvisynthCheckThread::m_avsDllPath[2]; -//Helper +//------------------------------------- +// Auxilary functions +//------------------------------------- + #define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists()) #define BOOLIFY(X) ((X) ? '1' : '0') -//Utility function QString AVS_CHECK_BINARY(const SysinfoModel *sysinfo, const bool& x64) { return QString("%1/toolset/%2/avs_check_%2.exe").arg(sysinfo->getAppPath(), (x64 ? "x64": "x86")); @@ -58,7 +59,6 @@ class Wow64RedirectionDisabler public: Wow64RedirectionDisabler(void) { - m_oldValue = NULL; m_disabled = MUtils::OS::wow64fsredir_disable(m_oldValue); } ~Wow64RedirectionDisabler(void) @@ -73,7 +73,7 @@ public: } private: bool m_disabled; - void* m_oldValue; + uintptr_t m_oldValue; }; //------------------------------------- @@ -140,8 +140,7 @@ AvisynthCheckThread::AvisynthCheckThread(const SysinfoModel *const sysinfo) : m_sysinfo(sysinfo) { - m_success = false; - m_exception = false; + m_basePath.clear(); } AvisynthCheckThread::~AvisynthCheckThread(void) @@ -150,48 +149,19 @@ AvisynthCheckThread::~AvisynthCheckThread(void) void AvisynthCheckThread::run(void) { - m_exception = false; - m_success &= 0; m_basePath.clear(); - - detectAvisynthVersion1(m_success, m_basePath, m_sysinfo, &m_exception); + StarupThread::run(); } -void AvisynthCheckThread::detectAvisynthVersion1(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception) +int AvisynthCheckThread::threadMain(void) { - __try - { - detectAvisynthVersion2(success, basePath, sysinfo, exception); - } - __except(1) - { - *exception = true; - qWarning("Unhandled exception error in Avisynth thread !!!"); - } -} - -void AvisynthCheckThread::detectAvisynthVersion2(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception) -{ - try - { - return detectAvisynthVersion3(success, basePath, sysinfo); - } - catch(...) - { - *exception = true; - qWarning("Avisynth initializdation raised an C++ exception!"); - } -} - -void AvisynthCheckThread::detectAvisynthVersion3(int &success, QString &basePath, const SysinfoModel *const sysinfo) -{ - success &= 0; + int flags = 0; QFile *avsPath32; - if(checkAvisynth(basePath, sysinfo, avsPath32, false)) + if(checkAvisynth(m_basePath, m_sysinfo, avsPath32, false)) { m_avsDllPath[0].reset(avsPath32); - success |= AVISYNTH_X86; + flags |= AVISYNTH_X86; qDebug("Avisynth 32-Bit edition found!"); } else @@ -199,13 +169,13 @@ void AvisynthCheckThread::detectAvisynthVersion3(int &success, QString &basePath qDebug("Avisynth 32-Bit edition *not* found!"); } - if(sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64)) + if(m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64)) { QFile *avsPath64; - if(checkAvisynth(basePath, sysinfo, avsPath64, true)) + if(checkAvisynth(m_basePath, m_sysinfo, avsPath64, true)) { m_avsDllPath[1].reset(avsPath64); - success |= AVISYNTH_X64; + flags |= AVISYNTH_X64; qDebug("Avisynth 64-Bit edition found!"); } else @@ -217,8 +187,14 @@ void AvisynthCheckThread::detectAvisynthVersion3(int &success, QString &basePath { qWarning("Skipping 64-Bit Avisynth check on non-x64 system!"); } + + return flags; } +//------------------------------------- +// Internal functions +//------------------------------------- + bool AvisynthCheckThread::checkAvisynth(QString &basePath, const SysinfoModel *const sysinfo, QFile *&path, const bool &x64) { qDebug("Avisynth %s-Bit support is being tested.", x64 ? "64" : "32"); diff --git a/src/thread_avisynth.h b/src/thread_avisynth.h index 7570a9c..dd2d728 100644 --- a/src/thread_avisynth.h +++ b/src/thread_avisynth.h @@ -39,8 +39,6 @@ protected: AvisynthCheckThread(const SysinfoModel *const sysinfo); ~AvisynthCheckThread(void); - int getSuccess(void) { return m_success; } - bool getException(void) { return m_exception; } QString getPath(void) { return m_basePath; } typedef enum _AvisynthFlags @@ -54,8 +52,6 @@ private slots: void start(Priority priority = InheritPriority) { QThread::start(priority); } private: - volatile bool m_exception; - int m_success; QString m_basePath; const SysinfoModel *const m_sysinfo; @@ -65,10 +61,8 @@ private: //Entry point virtual void run(void); - //Functions - static void detectAvisynthVersion1(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception); - static void detectAvisynthVersion2(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception); - static void detectAvisynthVersion3(int &success, QString &basePath, const SysinfoModel *const sysinfo); + //Thread main + virtual int threadMain(void); //Internal functions static bool checkAvisynth(QString &basePath, const SysinfoModel *const sysinfo, QFile *&path, const bool &x64); diff --git a/src/thread_binaries.cpp b/src/thread_binaries.cpp index 0df2e84..78314f3 100644 --- a/src/thread_binaries.cpp +++ b/src/thread_binaries.cpp @@ -48,6 +48,7 @@ QScopedPointer BinariesCheckThread::m_binPath[MAX_BINARIES]; //Whatever #define NEXT(X) ((*reinterpret_cast(&(X)))++) #define SHFL(X) ((*reinterpret_cast(&(X))) <<= 1) +#define BOOLIFY(X) (!!(X)) //External QString AVS_CHECK_BINARY(const SysinfoModel *sysinfo, const bool& x64); @@ -91,7 +92,7 @@ bool BinariesCheckThread::check(const SysinfoModel *const sysinfo, QString *cons return false; } - const bool success = thread.getSuccess(); + const bool success = BOOLIFY(thread.getSuccess()); if ((!success) && failedPath) { *failedPath = thread.getFailedPath(); @@ -108,7 +109,7 @@ BinariesCheckThread::BinariesCheckThread(const SysinfoModel *const sysinfo) : m_sysinfo(sysinfo) { - m_success = m_exception = false; + m_failedPath.clear(); } BinariesCheckThread::~BinariesCheckThread(void) @@ -117,41 +118,12 @@ BinariesCheckThread::~BinariesCheckThread(void) void BinariesCheckThread::run(void) { - m_success = m_exception = false; - m_failedPath = QString(); - checkBinaries1(m_success, m_failedPath, m_sysinfo, &m_exception); + m_failedPath.clear(); + StarupThread::run(); } -void BinariesCheckThread::checkBinaries1(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo, volatile bool *exception) +int BinariesCheckThread::threadMain(void) { - __try - { - checkBinaries2(success, failedPath, sysinfo, exception); - } - __except(1) - { - *exception = true; - qWarning("Unhandled exception error in binaries checker thread !!!"); - } -} - -void BinariesCheckThread::checkBinaries2(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo, volatile bool *exception) -{ - try - { - return checkBinaries3(success, failedPath, sysinfo); - } - catch(...) - { - *exception = true; - qWarning("Binaries checker initializdation raised an C++ exception!"); - } -} - -void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo) -{ - success = true; - //Create list of all required binary files typedef QPair FileEntry; QList binFiles; @@ -165,7 +137,7 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failed const QStringList variants = encInfo.getVariants(); for (quint32 varntIdx = 0; varntIdx < quint32(variants.count()); ++varntIdx) { - const QStringList dependencies = encInfo.getDependencies(sysinfo, archIdx, varntIdx); + const QStringList dependencies = encInfo.getDependencies(m_sysinfo, archIdx, varntIdx); for (QStringList::ConstIterator iter = dependencies.constBegin(); iter != dependencies.constEnd(); iter++) { if (!filesSet.contains(*iter)) @@ -174,7 +146,7 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failed binFiles << qMakePair(*iter, true); } } - const QString binary = encInfo.getBinaryPath(sysinfo, archIdx, varntIdx); + const QString binary = encInfo.getBinaryPath(m_sysinfo, archIdx, varntIdx); if (!filesSet.contains(binary)) { filesSet << binary; @@ -185,14 +157,14 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failed } for(int i = 0; i < 2; i++) { - binFiles << qMakePair(SourceFactory::getSourceInfo(SourceFactory::SourceType_AVS).getBinaryPath(sysinfo, bool(i)), false); - binFiles << qMakePair(AVS_CHECK_BINARY(sysinfo, bool(i)), false); + binFiles << qMakePair(SourceFactory::getSourceInfo(SourceFactory::SourceType_AVS).getBinaryPath(m_sysinfo, bool(i)), false); + binFiles << qMakePair(AVS_CHECK_BINARY(m_sysinfo, bool(i)), false); } for(size_t i = 0; UpdaterDialog::BINARIES[i].name; i++) { if(UpdaterDialog::BINARIES[i].exec) { - binFiles << qMakePair(QString("%1/toolset/common/%2").arg(sysinfo->getAppPath(), QString::fromLatin1(UpdaterDialog::BINARIES[i].name)), false); + binFiles << qMakePair(QString("%1/toolset/common/%2").arg(m_sysinfo->getAppPath(), QString::fromLatin1(UpdaterDialog::BINARIES[i].name)), false); } } @@ -209,20 +181,18 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failed { if (!MUtils::OS::is_executable_file(file->fileName())) { - failedPath = file->fileName(); - success = false; + m_failedPath = file->fileName(); qWarning("Required tool does NOT look like a valid Win32/Win64 binary:\n%s\n", MUTILS_UTF8(file->fileName())); - return; + return 0; } } else { if (!MUtils::OS::is_library_file(file->fileName())) { - failedPath = file->fileName(); - success = false; + m_failedPath = file->fileName(); qWarning("Required tool does NOT look like a valid Win32/Win64 library:\n%s\n", MUTILS_UTF8(file->fileName())); - return; + return 0; } } if(currentFile < MAX_BINARIES) @@ -234,10 +204,11 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, QString &failed } else { - failedPath = file->fileName(); - success = false; + m_failedPath = file->fileName(); qWarning("Required tool could not be found or access denied:\n%s\n", MUTILS_UTF8(file->fileName())); - return; + return 0; } } + + return 1; } diff --git a/src/thread_binaries.h b/src/thread_binaries.h index 0d00f0c..2356277 100644 --- a/src/thread_binaries.h +++ b/src/thread_binaries.h @@ -21,14 +21,16 @@ #pragma once -#include +#include "thread_startup.h" + +//Qt #include class QLibrary; class SysinfoModel; class QFile; -class BinariesCheckThread : public QThread +class BinariesCheckThread : public StarupThread { Q_OBJECT @@ -38,17 +40,10 @@ public: protected: BinariesCheckThread(const SysinfoModel *const sysinfo); ~BinariesCheckThread(void); - - int getSuccess(void) { return m_success; } - bool getException(void) { return m_exception; } const QString& getFailedPath(void) { return m_failedPath; } -private slots: - void start(Priority priority = InheritPriority) { QThread::start(priority); } - private: - volatile bool m_exception, m_success; QString m_failedPath; const SysinfoModel *const m_sysinfo; @@ -59,8 +54,6 @@ private: //Entry point virtual void run(void); - //Functions - static void checkBinaries1(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo, volatile bool *exception); - static void checkBinaries2(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo, volatile bool *exception); - static void checkBinaries3(volatile bool &success, QString &failedPath, const SysinfoModel *const sysinfo); + //Thread main + virtual int threadMain(void); }; diff --git a/src/thread_startup.cpp b/src/thread_startup.cpp index 9b7adff..33887f3 100644 --- a/src/thread_startup.cpp +++ b/src/thread_startup.cpp @@ -29,6 +29,61 @@ #include #include +//------------------------------------- +// Constructor +//------------------------------------- + +StarupThread::StarupThread(void) +{ + m_exception = false; + m_success = 0; +} + +StarupThread::~StarupThread(void) +{ +} + +//------------------------------------- +// Thread entry point +//------------------------------------- + +void StarupThread::run(void) +{ + m_exception = false; + m_success = 0; + runChecked1(this, m_success, &m_exception); +} + +void StarupThread::runChecked1(StarupThread *const thread, volatile int &success, volatile bool *exception) +{ + __try + { + return runChecked2(thread, success, exception); + } + __except(1) + { + *exception = true; + qWarning("Unhandled exception error in startup thread !!!"); + } +} + +void StarupThread::runChecked2(StarupThread *const thread, volatile int &success, volatile bool *exception) +{ + try + { + success = thread->threadMain(); + } + catch(...) + { + *exception = true; + qWarning("Startup thread raised an C++ exception!"); + } +} + +//------------------------------------- +// Utility functions +//------------------------------------- + QStringList StarupThread::runProcess(const QString &exePath, const QStringList &arguments, const QStringList *const extraPaths) { QProcess process; @@ -64,10 +119,18 @@ QStringList StarupThread::runProcess(const QString &exePath, const QStringList & processOutput << line; } } - if (timer.hasExpired(15000)) + if ((process.state() != QProcess::NotRunning) && timer.hasExpired(15000)) + { + process.waitForFinished(125); + if (process.state() != QProcess::NotRunning) + { + qWarning("%s process encountered a deadlock -> aborting now!", MUTILS_UTF8(fileName)); + break; + } + } + else { - qWarning("%s process encountered a deadlock -> aborting now!", MUTILS_UTF8(fileName)); - break; + QThread::yieldCurrentThread(); /*yield*/ } } diff --git a/src/thread_startup.h b/src/thread_startup.h index d187bf2..ab9bb78 100644 --- a/src/thread_startup.h +++ b/src/thread_startup.h @@ -29,6 +29,30 @@ class StarupThread : public QThread { Q_OBJECT +public: + StarupThread(void); + ~StarupThread(void); + + bool getException(void) { return m_exception; } + int getSuccess(void) { return m_success; } + +protected slots: + void start(Priority priority = InheritPriority) { QThread::start(priority); } + protected: + volatile int m_success; + volatile bool m_exception; + + //Entry point + virtual void run(void); + + //Error handling + static void runChecked1(StarupThread *const thread, volatile int &success, volatile bool *exception); + static void runChecked2(StarupThread *const thread, volatile int &success, volatile bool *exception); + + //Thread main + virtual int threadMain(void) = 0; + + //Utility functions static QStringList runProcess(const QString &exePath, const QStringList &args, const QStringList *const extraPaths = NULL); }; diff --git a/src/thread_vapoursynth.cpp b/src/thread_vapoursynth.cpp index 26e6361..22efd7b 100644 --- a/src/thread_vapoursynth.cpp +++ b/src/thread_vapoursynth.cpp @@ -26,7 +26,6 @@ #include //Qt -#include #include #include #include @@ -47,6 +46,10 @@ QMutex VapourSynthCheckThread::m_vpsLock; QScopedPointer VapourSynthCheckThread::m_vpsExePath[2]; QScopedPointer VapourSynthCheckThread::m_vpsDllPath[2]; +//------------------------------------- +// Auxilary functions +//------------------------------------- + #define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists()) #define BOOLIFY(X) ((X) ? '1' : '0') #define VPS_BITNESS(X) (((X) + 1U) * 32U) @@ -122,13 +125,11 @@ bool VapourSynthCheckThread::detect(SysinfoModel *sysinfo) } //------------------------------------- -// Thread class +// Thread functions //------------------------------------- VapourSynthCheckThread::VapourSynthCheckThread(void) { - m_success &= 0; - m_exception = false; m_vpsPath.clear(); } @@ -138,44 +139,12 @@ VapourSynthCheckThread::~VapourSynthCheckThread(void) void VapourSynthCheckThread::run(void) { - m_success &= 0; - m_exception = false; m_vpsPath.clear(); - - detectVapourSynthPath1(m_success, m_vpsPath, &m_exception); -} - -void VapourSynthCheckThread::detectVapourSynthPath1(int &success, QString &path, volatile bool *exception) -{ - __try - { - return detectVapourSynthPath2(success, path, exception); - } - __except(1) - { - *exception = true; - qWarning("Unhandled exception error in VapourSynth thread !!!"); - } + StarupThread::run(); } -void VapourSynthCheckThread::detectVapourSynthPath2(int &success, QString &path, volatile bool *exception) +int VapourSynthCheckThread::threadMain(void) { - try - { - return detectVapourSynthPath3(success, path); - } - catch(...) - { - *exception = true; - qWarning("VapourSynth initializdation raised an C++ exception!"); - } -} - -void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) -{ - success &= 0; - path.clear(); - static const char *VPS_CORE_DIR[] = { "core32", @@ -209,6 +178,7 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) }; QString vapoursynthPath; + int flags = 0; //Look for "portable" VapourSynth version if (ENABLE_PORTABLE_VPS) @@ -267,7 +237,7 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) if(vapoursynthPath.isEmpty()) { qWarning("VapourSynth install path not found -> disable VapouSynth support!"); - return; + return 0; } //Validate the VapourSynth installation now! @@ -279,7 +249,7 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) { if (vpsExeFile && checkVapourSynth(vpsExeFile->fileName())) { - success |= VPS_BIT_FLAG[i]; + flags |= VPS_BIT_FLAG[i]; qDebug("VapourSynth %u-Bit edition found!", VPS_BITNESS(i)); m_vpsExePath[i].reset(vpsExeFile); m_vpsDllPath[i].reset(vpsDllFile); @@ -296,12 +266,18 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) } //Return VapourSynth path - if(success) + if(flags) { - path = vapoursynthPath; + m_vpsPath = vapoursynthPath; } + + return flags; } +//------------------------------------- +// Internal functions +//------------------------------------- + bool VapourSynthCheckThread::isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile) { bool complete = false; diff --git a/src/thread_vapoursynth.h b/src/thread_vapoursynth.h index ddc514b..83b9d76 100644 --- a/src/thread_vapoursynth.h +++ b/src/thread_vapoursynth.h @@ -37,13 +37,6 @@ public: static bool detect(SysinfoModel *sysinfo); protected: - VapourSynthCheckThread(void); - ~VapourSynthCheckThread(void); - - bool getException(void) { return m_exception; } - int getSuccess(void) { return m_success; } - QString getPath(void) { return m_vpsPath; } - typedef enum _VapourSynthFlags { VAPOURSYNTH_X86 = 0x1, @@ -51,12 +44,12 @@ protected: } VapourSynthFlags; -private slots: - void start(Priority priority = InheritPriority) { QThread::start(priority); } + VapourSynthCheckThread(void); + ~VapourSynthCheckThread(void); + + QString getPath(void) { return m_vpsPath; } private: - volatile bool m_exception; - int m_success; QString m_vpsPath; static QMutex m_vpsLock; @@ -66,10 +59,8 @@ private: //Entry point virtual void run(void); - //Functions - static void detectVapourSynthPath1(int &success, QString &path, volatile bool *exception); - static void detectVapourSynthPath2(int &success, QString &path, volatile bool *exception); - static void detectVapourSynthPath3(int &success, QString &path); + //Thread main + virtual int threadMain(void); //Internal functions static bool isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile); diff --git a/src/version.h b/src/version.h index 5c0715f..02acb1e 100644 --- a/src/version.h +++ b/src/version.h @@ -26,7 +26,7 @@ #define VER_X264_MAJOR 2 #define VER_X264_MINOR 9 #define VER_X264_PATCH 0 -#define VER_X264_BUILD 1154 +#define VER_X264_BUILD 1156 #define VER_X264_PORTABLE_EDITION (0) -- 2.11.0