diff options
Diffstat (limited to 'src/corelib/thread/qmutex.h')
-rw-r--r-- | src/corelib/thread/qmutex.h | 90 |
1 files changed, 61 insertions, 29 deletions
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 837355a602..c693ff65d8 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -57,11 +57,13 @@ QT_BEGIN_NAMESPACE #if QT_CONFIG(thread) || defined(Q_CLANG_QDOC) #ifdef Q_OS_LINUX -# define QT_MUTEX_LOCK_NOEXCEPT Q_DECL_NOTHROW +# define QT_MUTEX_LOCK_NOEXCEPT noexcept #else # define QT_MUTEX_LOCK_NOEXCEPT #endif +class QMutex; +class QRecursiveMutex; class QMutexData; class Q_CORE_EXPORT QBasicMutex @@ -80,39 +82,39 @@ public: } // BasicLockable concept - inline void unlock() Q_DECL_NOTHROW { - Q_ASSERT(d_ptr.load()); //mutex must be locked + inline void unlock() noexcept { + Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked if (!fastTryUnlock()) unlockInternal(); } - bool tryLock() Q_DECL_NOTHROW { + bool tryLock() noexcept { return fastTryLock(); } // Lockable concept - bool try_lock() Q_DECL_NOTHROW { return tryLock(); } + bool try_lock() noexcept { return tryLock(); } - bool isRecursive() Q_DECL_NOTHROW; //### Qt6: remove me - bool isRecursive() const Q_DECL_NOTHROW; + bool isRecursive() noexcept; //### Qt6: remove me + bool isRecursive() const noexcept; private: - inline bool fastTryLock() Q_DECL_NOTHROW { + inline bool fastTryLock() noexcept { return d_ptr.testAndSetAcquire(nullptr, dummyLocked()); } - inline bool fastTryUnlock() Q_DECL_NOTHROW { + inline bool fastTryUnlock() noexcept { return d_ptr.testAndSetRelease(dummyLocked(), nullptr); } - inline bool fastTryLock(QMutexData *¤t) Q_DECL_NOTHROW { + inline bool fastTryLock(QMutexData *¤t) noexcept { return d_ptr.testAndSetAcquire(nullptr, dummyLocked(), current); } - inline bool fastTryUnlock(QMutexData *¤t) Q_DECL_NOTHROW { + inline bool fastTryUnlock(QMutexData *¤t) noexcept { return d_ptr.testAndSetRelease(dummyLocked(), nullptr, current); } void lockInternal() QT_MUTEX_LOCK_NOEXCEPT; bool lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT; - void unlockInternal() Q_DECL_NOTHROW; + void unlockInternal() noexcept; QBasicAtomicPointer<QMutexData> d_ptr; static inline QMutexData *dummyLocked() { @@ -120,21 +122,27 @@ private: } friend class QMutex; + friend class QRecursiveMutex; friend class QMutexData; }; class Q_CORE_EXPORT QMutex : public QBasicMutex { public: +#if defined(Q_COMPILER_CONSTEXPR) + constexpr QMutex() = default; +#else + QMutex() { d_ptr.storeRelaxed(nullptr); } +#endif enum RecursionMode { NonRecursive, Recursive }; - explicit QMutex(RecursionMode mode = NonRecursive); + explicit QMutex(RecursionMode mode); ~QMutex(); // BasicLockable concept void lock() QT_MUTEX_LOCK_NOEXCEPT; bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT; // BasicLockable concept - void unlock() Q_DECL_NOTHROW; + void unlock() noexcept; // Lockable concept bool try_lock() QT_MUTEX_LOCK_NOEXCEPT { return tryLock(); } @@ -158,12 +166,13 @@ public: } #endif - bool isRecursive() const Q_DECL_NOTHROW + bool isRecursive() const noexcept { return QBasicMutex::isRecursive(); } private: Q_DISABLE_COPY(QMutex) friend class QMutexLocker; + friend class QRecursiveMutex; friend class ::tst_QMutex; #if QT_HAS_INCLUDE(<chrono>) @@ -192,6 +201,24 @@ private: #endif }; +class QRecursiveMutex : private QMutex +{ + // ### Qt 6: make it independent of QMutex + friend class QMutexLocker; +public: + Q_CORE_EXPORT QRecursiveMutex(); + Q_CORE_EXPORT ~QRecursiveMutex(); + + using QMutex::lock; + using QMutex::tryLock; + using QMutex::unlock; + using QMutex::try_lock; +#if QT_HAS_INCLUDE(<chrono>) + using QMutex::try_lock_for; + using QMutex::try_lock_until; +#endif +}; + class Q_CORE_EXPORT QMutexLocker { public: @@ -207,12 +234,15 @@ public: val |= 1; } } + explicit QMutexLocker(QRecursiveMutex *m) QT_MUTEX_LOCK_NOEXCEPT + : QMutexLocker{static_cast<QBasicMutex*>(m)} {} #else QMutexLocker(QMutex *) { } + QMutexLocker(QRecursiveMutex *) {} #endif inline ~QMutexLocker() { unlock(); } - inline void unlock() Q_DECL_NOTHROW + inline void unlock() noexcept { if ((val & quintptr(1u)) == quintptr(1u)) { val &= ~quintptr(1u); @@ -257,24 +287,24 @@ class Q_CORE_EXPORT QMutex public: enum RecursionMode { NonRecursive, Recursive }; - inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) Q_DECL_NOTHROW { } + inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) noexcept { } - inline void lock() Q_DECL_NOTHROW {} - inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; } - inline bool try_lock() Q_DECL_NOTHROW { return true; } - inline void unlock() Q_DECL_NOTHROW {} - inline bool isRecursive() const Q_DECL_NOTHROW { return true; } + inline void lock() noexcept {} + inline bool tryLock(int timeout = 0) noexcept { Q_UNUSED(timeout); return true; } + inline bool try_lock() noexcept { return true; } + inline void unlock() noexcept {} + inline bool isRecursive() const noexcept { return true; } #if QT_HAS_INCLUDE(<chrono>) template <class Rep, class Period> - inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) Q_DECL_NOTHROW + inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) noexcept { Q_UNUSED(duration); return true; } template<class Clock, class Duration> - inline bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint) Q_DECL_NOTHROW + inline bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint) noexcept { Q_UNUSED(timePoint); return true; @@ -285,15 +315,17 @@ private: Q_DISABLE_COPY(QMutex) }; +class QRecursiveMutex : public QMutex {}; + class Q_CORE_EXPORT QMutexLocker { public: - inline explicit QMutexLocker(QMutex *) Q_DECL_NOTHROW {} - inline ~QMutexLocker() Q_DECL_NOTHROW {} + inline explicit QMutexLocker(QMutex *) noexcept {} + inline ~QMutexLocker() noexcept {} - inline void unlock() Q_DECL_NOTHROW {} - void relock() Q_DECL_NOTHROW {} - inline QMutex *mutex() const Q_DECL_NOTHROW { return nullptr; } + inline void unlock() noexcept {} + void relock() noexcept {} + inline QMutex *mutex() const noexcept { return nullptr; } private: Q_DISABLE_COPY(QMutexLocker) |