diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-08-02 16:15:22 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-25 10:35:26 +0200 |
commit | c28204066c2d3bae989132ab15e8df437ae38f3d (patch) | |
tree | 989935de1629ae724d8826f16244e85907ad7043 /src/corelib/thread/qmutex.h | |
parent | 98437f0e2edde7f5e49e1a6bea27ef130b58bee4 (diff) |
Mark mutex locking and unlocking functions with noexcept
Unlocking a mutex can never throw an exception. That doesn't make
sense and our code should make sure it can't happen. Right now,
provided that the system-level functions don't throw, we don't either.
Locking a mutex cannot throw on Linux because we use futexes
directly. A non-recursive mutex is just a futex, whereas a recursive
mutex uses a mutex (a futex) to manage a lock count.
However, on other platforms, due to the freelist, there can be memory
allocation, which means it might throw std::bad_alloc. Not because of
the freelist itself (that uses malloc and will just crash if malloc
fails) but because of Q_GLOBAL_STATIC. In 5.1, the global static will
be noexcept provided the type's constructor is so too (it is, in this
case).
Change-Id: I4c562383f48de1be7827b9afb512d73eaf0792d5
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread/qmutex.h')
-rw-r--r-- | src/corelib/thread/qmutex.h | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 4fe4df09c6..5d4d6969f5 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -53,34 +53,40 @@ QT_BEGIN_NAMESPACE #if !defined(QT_NO_THREAD) && !defined(qdoc) +#ifdef Q_OS_LINUX +# define QT_MUTEX_LOCK_NOEXCEPT Q_DECL_NOTHROW +#else +# define QT_MUTEX_LOCK_NOEXCEPT +#endif + class QMutexData; class Q_CORE_EXPORT QBasicMutex { public: - inline void lock() { + inline void lock() QT_MUTEX_LOCK_NOEXCEPT { if (!fastTryLock()) lockInternal(); } - inline void unlock() { + inline void unlock() Q_DECL_NOTHROW { Q_ASSERT(d_ptr.load()); //mutex must be locked if (!d_ptr.testAndSetRelease(dummyLocked(), 0)) unlockInternal(); } - bool tryLock(int timeout = 0) { + bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT { return fastTryLock() || lockInternal(timeout); } bool isRecursive(); private: - inline bool fastTryLock() { + inline bool fastTryLock() Q_DECL_NOTHROW { return d_ptr.testAndSetAcquire(0, dummyLocked()); } - bool lockInternal(int timeout = -1); - void unlockInternal(); + bool lockInternal(int timeout = -1) QT_MUTEX_LOCK_NOEXCEPT; + void unlockInternal() Q_DECL_NOTHROW; QBasicAtomicPointer<QMutexData> d_ptr; static inline QMutexData *dummyLocked() { @@ -97,9 +103,9 @@ public: explicit QMutex(RecursionMode mode = NonRecursive); ~QMutex(); - void lock(); - bool tryLock(int timeout = 0); - void unlock(); + void lock() QT_MUTEX_LOCK_NOEXCEPT; + bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT; + void unlock() Q_DECL_NOTHROW; using QBasicMutex::isRecursive; @@ -111,7 +117,7 @@ private: class Q_CORE_EXPORT QMutexLocker { public: - inline explicit QMutexLocker(QBasicMutex *m) + inline explicit QMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT { Q_ASSERT_X((reinterpret_cast<quintptr>(m) & quintptr(1u)) == quintptr(0), "QMutexLocker", "QMutex pointer is misaligned"); @@ -124,7 +130,7 @@ public: } inline ~QMutexLocker() { unlock(); } - inline void unlock() + inline void unlock() Q_DECL_NOTHROW { if ((val & quintptr(1u)) == quintptr(1u)) { val &= ~quintptr(1u); @@ -132,7 +138,7 @@ public: } } - inline void relock() + inline void relock() QT_MUTEX_LOCK_NOEXCEPT { if (val) { if ((val & quintptr(1u)) == quintptr(0u)) { @@ -162,8 +168,6 @@ private: quintptr val; }; - - #else // QT_NO_THREAD or qdoc class Q_CORE_EXPORT QMutex |