summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qmutex.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-08-02 16:15:22 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-25 10:35:26 +0200
commitc28204066c2d3bae989132ab15e8df437ae38f3d (patch)
tree989935de1629ae724d8826f16244e85907ad7043 /src/corelib/thread/qmutex.h
parent98437f0e2edde7f5e49e1a6bea27ef130b58bee4 (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.h32
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