diff --git a/include/MUtils/Global.h b/include/MUtils/Global.h index 3acb912..19273e9 100644 --- a/include/MUtils/Global.h +++ b/include/MUtils/Global.h @@ -361,6 +361,10 @@ namespace MUtils */ #define MUTILS_BOOL2STR(X) ((X) ? "1" : "0") +/** \brief Converts a given expression into a boolean expression, by application of double negation operator. +*/ +#define MUTILS_BOOLIFY(X) (!(!(X))) + /** \brief Disables copy constructor and assignment operator in the specified class. This macro should be used in the "private" section of the class' declaration. */ #define MUTILS_NO_COPY(CLASS) \ diff --git a/include/MUtils/UpdateChecker.h b/include/MUtils/UpdateChecker.h index fe47d77..d5f0ed8 100644 --- a/include/MUtils/UpdateChecker.h +++ b/include/MUtils/UpdateChecker.h @@ -120,7 +120,7 @@ namespace MUtils const QString m_binaryGnuPG; const QString m_binaryKeys; - volatile bool m_success; + QAtomicInt m_success; QAtomicInt m_cancelled; int m_status; diff --git a/src/CriticalSection_Win32.h b/src/CriticalSection_Win32.h index fc4204b..f0ae0a0 100644 --- a/src/CriticalSection_Win32.h +++ b/src/CriticalSection_Win32.h @@ -78,11 +78,10 @@ namespace MUtils public: inline CSLocker(CriticalSection &criticalSection) : - m_locked(false), m_criticalSection(criticalSection) { m_criticalSection.enter(); - m_locked = true; + m_locked.ref(); } inline ~CSLocker(void) @@ -92,14 +91,13 @@ namespace MUtils inline void forceUnlock(void) { - if(m_locked) + if (m_locked.fetchAndStoreOrdered(0) > 0) { m_criticalSection.leave(); - m_locked = false; } } protected: - volatile bool m_locked; + QAtomicInt m_locked; CriticalSection &m_criticalSection; }; } diff --git a/src/Taskbar7_Win32.cpp b/src/Taskbar7_Win32.cpp index f97b137..f425729 100644 --- a/src/Taskbar7_Win32.cpp +++ b/src/Taskbar7_Win32.cpp @@ -51,7 +51,7 @@ { \ return false; \ } \ - if(!(p->initialized || initialize())) \ + if(!(MUTILS_BOOLIFY(p->initialized) || initialize())) \ { \ qWarning("Taskbar initialization failed!"); \ return false; \ @@ -73,13 +73,11 @@ namespace MUtils Taskbar7_Private(void) { taskbarList = NULL; - supported = false; - initialized = false; } ITaskbarList3 *taskbarList; - volatile bool supported; - volatile bool initialized; + QAtomicInt supported; + QAtomicInt initialized; }; } @@ -96,9 +94,16 @@ MUtils::Taskbar7::Taskbar7(QWidget *const window) { MUTILS_THROW("Taskbar7: Window pointer must not be NULL!"); } - if(!(p->supported = (OS::os_version() >= OS::Version::WINDOWS_WIN70))) + if (!p->supported) { - qWarning("Taskbar7: Taskbar progress not supported on this platform."); + if (OS::os_version() >= OS::Version::WINDOWS_WIN70) + { + p->supported.ref(); + } + else + { + qWarning("Taskbar7: Taskbar progress not supported on this platform."); + } } } @@ -190,7 +195,7 @@ bool MUtils::Taskbar7::initialize(void) p->taskbarList = ptbl; } - while(!p->initialized) + if(!p->initialized) { bool okay = false; for(int i = 0; i < 8; i++) @@ -207,7 +212,7 @@ bool MUtils::Taskbar7::initialize(void) qWarning("ITaskbarList3::HrInit() has failed!"); return false; } - p->initialized = true; + p->initialized.ref(); /*success*/ } return true; diff --git a/src/Terminal_Win32.cpp b/src/Terminal_Win32.cpp index 03a76f3..dfb7e9b 100644 --- a/src/Terminal_Win32.cpp +++ b/src/Terminal_Win32.cpp @@ -59,7 +59,7 @@ static MUtils::Internal::CriticalSection g_terminal_lock; //Is terminal attached? -static volatile bool g_terminal_attached = false; +static QAtomicInt g_terminal_attached; //Terminal output buffer static const size_t BUFF_SIZE = 8192; @@ -176,7 +176,7 @@ static void terminal_shutdown(void) { MUtils::Internal::CSLocker lock(g_terminal_lock); - if (g_terminal_attached) + if (g_terminal_attached.fetchAndStoreOrdered(0) > 0) { g_fileBuf_stdout.reset(); g_fileBuf_stderr.reset(); @@ -185,7 +185,6 @@ static void terminal_shutdown(void) if(stderr) freopen_s(&temp[1], "NUL", "wb", stderr); FreeConsole(); set_hicon(&g_terminal_icon, NULL); - g_terminal_attached = false; } } @@ -229,7 +228,7 @@ void MUtils::Terminal::setup(int &argc, char **argv, const char* const appName, if(enableConsole) { - if(!g_terminal_attached) + if(!g_terminal_attached.fetchAndStoreOrdered(1)) { if(AllocConsole() != FALSE) { @@ -241,11 +240,14 @@ void MUtils::Terminal::setup(int &argc, char **argv, const char* const appName, _snprintf_s(title, 128, _TRUNCATE, "%s | Debug Console", appName); SetConsoleTitleA(title); } - g_terminal_attached = true; + } + else + { + g_terminal_attached.fetchAndStoreOrdered(0); /*failed*/ } } - if(g_terminal_attached) + if(MUTILS_BOOLIFY(g_terminal_attached)) { g_fileBuf_stdout.reset(terminal_connect(stdout, std::cout)); g_fileBuf_stderr.reset(terminal_connect(stderr, std::cerr)); @@ -394,7 +396,7 @@ void MUtils::Terminal::write(const int &type, const char *const message) { MUtils::Internal::CSLocker lock(g_terminal_lock); - if(g_terminal_attached) + if(MUTILS_BOOLIFY(g_terminal_attached)) { write_to_terminal(type, message); } @@ -417,7 +419,7 @@ void MUtils::Terminal::set_icon(const QIcon &icon) { MUtils::Internal::CSLocker lock(g_terminal_lock); - if(g_terminal_attached && (!(icon.isNull() || MUtils::OS::running_on_wine()))) + if(MUTILS_BOOLIFY(g_terminal_attached) && (!(icon.isNull() || MUtils::OS::running_on_wine()))) { if(const HICON hIcon = (HICON) MUtils::Win32Utils::qicon_to_hicon(&icon, 16, 16)) { diff --git a/src/UpdateChecker.cpp b/src/UpdateChecker.cpp index 4644160..f996bb6 100644 --- a/src/UpdateChecker.cpp +++ b/src/UpdateChecker.cpp @@ -222,12 +222,11 @@ static const int DOWNLOAD_TIMEOUT = 30000; static const int VERSION_INFO_EXPIRES_MONTHS = 6; static char *USER_AGENT_STR = "Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0"; /*use something innocuous*/ -#define IS_CANCELLED (!(!m_cancelled)) #define CHECK_CANCELLED() do \ { \ - if(IS_CANCELLED) \ + if(MUTILS_BOOLIFY(m_cancelled)) \ { \ - m_success = false; \ + m_success.fetchAndStoreOrdered(0); \ log("", "Update check has been cancelled by user!"); \ setProgress(m_maxProgress); \ setStatus(UpdateStatus_CancelledByUser); \ @@ -312,7 +311,6 @@ UpdateChecker::UpdateChecker(const QString &binWGet, const QString &binMCat, con m_testMode(testMode), m_maxProgress(getMaxProgress()) { - m_success = false; m_status = UpdateStatus_NotStartedYet; m_progress = 0; @@ -332,7 +330,7 @@ UpdateChecker::~UpdateChecker(void) void UpdateChecker::start(Priority priority) { - m_success = false; + m_success.fetchAndStoreOrdered(0); m_cancelled.fetchAndStoreOrdered(0); QThread::start(priority); } @@ -427,7 +425,7 @@ endLoop: const bool isQuick = (mirrorCount++ < QUICK_MIRRORS); if(tryUpdateMirror(m_updateInfo.data(), currentMirror, isQuick)) { - m_success = true; /*success*/ + m_success.ref(); /*success*/ break; } if (isQuick) @@ -447,7 +445,7 @@ endLoop: // ----- Generate final result ----- // - if(m_success) + if(MUTILS_BOOLIFY(m_success)) { if(m_updateInfo->m_buildNo > m_installedBuildNo) { @@ -694,7 +692,7 @@ bool UpdateChecker::getFile(const QString &url, const QString &outFile, const un { return true; } - if (IS_CANCELLED) + if (MUTILS_BOOLIFY(m_cancelled)) { break; /*cancelled*/ } @@ -759,7 +757,7 @@ bool UpdateChecker::getFile(const QString &url, const bool forceIp4, const QStri const QString line = QString::fromLatin1(process.readLine()).simplified(); log(line); } - if (bTimeOut || IS_CANCELLED) + if (bTimeOut || MUTILS_BOOLIFY(m_cancelled)) { qWarning("WGet process timed out <-- killing!"); process.kill(); @@ -813,7 +811,7 @@ bool UpdateChecker::tryContactHost(const QString &hostname, const int &timeoutMs QString line = QString::fromLatin1(process.readLine()).simplified(); log(line); } - if (bTimeOut || IS_CANCELLED) + if (bTimeOut || MUTILS_BOOLIFY(m_cancelled)) { qWarning("MCat process timed out <-- killing!"); process.kill();