diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-09-04 10:41:56 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-10-17 12:02:49 +0200 |
commit | 77d812683f0ad595606f9833613dd49bb2fda26d (patch) | |
tree | c1fb2f4a3e680db9c5597574fe8684571da0e0f5 /src/corelib/thread | |
parent | f76530a6171ca417865863b66e3ea439c27d057e (diff) |
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 <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qmutex.cpp | 2 | ||||
-rw-r--r-- | src/corelib/thread/qmutex.h | 71 | ||||
-rw-r--r-- | src/corelib/thread/qorderedmutexlocker_p.h | 2 |
3 files changed, 31 insertions, 44 deletions
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<typename Mutex> 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<typename Mutex> friend class QMutexLocker; public: Q_CORE_EXPORT QRecursiveMutex(); @@ -222,65 +224,49 @@ public: #endif }; -class Q_CORE_EXPORT QMutexLocker +template <typename Mutex> +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<quintptr>(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<QMutex *>(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<QBasicMutex*>(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<QMutex *>(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<typename Mutex> +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<QBasicMutex>; #endif |