summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-09-04 10:41:56 +0200
committerLars Knoll <lars.knoll@qt.io>2020-10-17 12:02:49 +0200
commit77d812683f0ad595606f9833613dd49bb2fda26d (patch)
treec1fb2f4a3e680db9c5597574fe8684571da0e0f5 /src/corelib/thread
parentf76530a6171ca417865863b66e3ea439c27d057e (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.cpp2
-rw-r--r--src/corelib/thread/qmutex.h71
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h2
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