From 77d812683f0ad595606f9833613dd49bb2fda26d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 4 Sep 2020 10:41:56 +0200 Subject: Refactor QMutexLocker to be able to handle recursive mutexes Since we're going to split QMutex and QRecursiveMutex into separate classes, make sure QMutexLocker is prepared for that. Change-Id: Id5e9a955d1db7c8ee663dd3811ad6448dad0aeae Reviewed-by: Volker Hilsheimer --- src/corelib/thread/qmutex.cpp | 2 +- src/corelib/thread/qmutex.h | 71 ++++++++++++------------------ src/corelib/thread/qorderedmutexlocker_p.h | 2 +- 3 files changed, 31 insertions(+), 44 deletions(-) (limited to 'src/corelib/thread') diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 7ae07a3aa2..531f417f92 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -423,7 +423,7 @@ QRecursiveMutex::~QRecursiveMutex() \ingroup thread - Locking and unlocking a QMutex in complex functions and + Locking and unlocking a QMutex or QRecursiveMutex in complex functions and statements or in exception handling code is error-prone and difficult to debug. QMutexLocker can be used in such situations to ensure that the state of the mutex is always well-defined. diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index b29a7e3a9b..9042ce5f5e 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -174,6 +174,7 @@ public: private: Q_DISABLE_COPY(QMutex) + template friend class QMutexLocker; friend class QRecursiveMutex; friend class ::tst_QMutex; @@ -207,6 +208,7 @@ private: class QRecursiveMutex : private QMutex { // ### Qt 6: make it independent of QMutex + template friend class QMutexLocker; public: Q_CORE_EXPORT QRecursiveMutex(); @@ -222,65 +224,49 @@ public: #endif }; -class Q_CORE_EXPORT QMutexLocker +template +class QMutexLocker { public: -#ifndef Q_CLANG_QDOC - inline explicit QMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT + inline explicit QMutexLocker(Mutex *mutex) QT_MUTEX_LOCK_NOEXCEPT { - Q_ASSERT_X((reinterpret_cast(m) & quintptr(1u)) == quintptr(0), - "QMutexLocker", "QMutex pointer is misaligned"); - val = quintptr(m); - if (Q_LIKELY(m)) { - // call QMutex::lock() instead of QBasicMutex::lock() - static_cast(m)->lock(); - val |= 1; + m = mutex; + if (Q_LIKELY(mutex)) { + mutex->lock(); + isLocked = true; } } - explicit QMutexLocker(QRecursiveMutex *m) QT_MUTEX_LOCK_NOEXCEPT - : QMutexLocker{static_cast(m)} {} -#else - QMutexLocker(QMutex *) { } - QMutexLocker(QRecursiveMutex *) {} -#endif - inline ~QMutexLocker() { unlock(); } + inline ~QMutexLocker() { + unlock(); + } inline void unlock() noexcept { - if ((val & quintptr(1u)) == quintptr(1u)) { - val &= ~quintptr(1u); - mutex()->unlock(); - } + if (!isLocked) + return; + m->unlock(); + isLocked = false; } inline void relock() QT_MUTEX_LOCK_NOEXCEPT { - if (val) { - if ((val & quintptr(1u)) == quintptr(0u)) { - mutex()->lock(); - val |= quintptr(1u); - } + if (isLocked) + return; + if (m) { + m->lock(); + isLocked = true; } } -#if defined(Q_CC_MSVC) -#pragma warning( push ) -#pragma warning( disable : 4312 ) // ignoring the warning from /Wp64 -#endif - - inline QMutex *mutex() const + Mutex *mutex() const { - return reinterpret_cast(val & ~quintptr(1u)); + return m; } - -#if defined(Q_CC_MSVC) -#pragma warning( pop ) -#endif - private: Q_DISABLE_COPY(QMutexLocker) - quintptr val; + Mutex *m; + bool isLocked = false; }; #else // !QT_CONFIG(thread) && !Q_CLANG_QDOC @@ -320,15 +306,16 @@ private: class QRecursiveMutex : public QMutex {}; -class Q_CORE_EXPORT QMutexLocker +template +class QMutexLocker { public: - inline explicit QMutexLocker(QMutex *) noexcept {} + inline explicit QMutexLocker(Mutex *) noexcept {} inline ~QMutexLocker() noexcept {} inline void unlock() noexcept {} void relock() noexcept {} - inline QMutex *mutex() const noexcept { return nullptr; } + inline Mutex *mutex() const noexcept { return nullptr; } private: Q_DISABLE_COPY(QMutexLocker) diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h index 83edfd5879..abd9b56c94 100644 --- a/src/corelib/thread/qorderedmutexlocker_p.h +++ b/src/corelib/thread/qorderedmutexlocker_p.h @@ -162,7 +162,7 @@ public: static bool relock(QBasicMutex *, QBasicMutex *) { return false; } }; -using QBasicMutexLocker = QMutexLocker; +using QBasicMutexLocker = QMutexLocker; #endif -- cgit v1.2.3