summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/thread/qmutex.cpp34
-rw-r--r--src/corelib/thread/qmutex.h13
-rw-r--r--tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp67
3 files changed, 114 insertions, 0 deletions
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index dec0a95c47..94e0fd25b1 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -486,6 +486,40 @@ void QRecursiveMutex::unlock() noexcept
*/
/*!
+ \fn template <typename Mutex> QMutexLocker<Mutex>::QMutexLocker(QMutexLocker &&other) noexcept
+ \since 6.4
+
+ Move-constructs a QMutexLocker from \a other. The mutex and the
+ state of \a other is transferred to the newly constructed instance.
+ After the move, \a other will no longer be managing its mutex.
+
+ \sa QMutex::lock()
+*/
+
+/*!
+ \fn template <typename Mutex> QMutexLocker<Mutex> &QMutexLocker<Mutex>::operator=(QMutexLocker &&other) noexcept
+ \since 6.4
+
+ Move-assigns \a other onto this QMutexLocker. If this QMutexLocker
+ was holding a locked mutex before the assignment, the mutex will be
+ unlocked. The mutex and the state of \a other is then transferred
+ to this QMutexLocker. After the move, \a other will no longer be
+ managing its mutex.
+
+ \sa QMutex::lock()
+*/
+
+/*!
+ \fn template <typename Mutex> void QMutexLocker<Mutex>::swap(QMutexLocker &other) noexcept
+ \since 6.4
+
+ Swaps the mutex and the state of this QMutexLocker with \a other.
+ This operation is very fast and never fails.
+
+ \sa QMutex::lock()
+*/
+
+/*!
\fn template <typename Mutex> QMutexLocker<Mutex>::~QMutexLocker() noexcept
Destroys the QMutexLocker and unlocks the mutex that was locked
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index f57a95de22..e10a3f8f3d 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -247,6 +247,13 @@ public:
}
}
+ inline QMutexLocker(QMutexLocker &&other) noexcept
+ : m_mutex(std::exchange(other.m_mutex, nullptr)),
+ m_isLocked(std::exchange(other.m_isLocked, false))
+ {}
+
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMutexLocker)
+
inline ~QMutexLocker()
{
unlock();
@@ -275,6 +282,12 @@ public:
}
}
+ inline void swap(QMutexLocker &other) noexcept
+ {
+ qt_ptr_swap(m_mutex, other.m_mutex);
+ std::swap(m_isLocked, other.m_isLocked);
+ }
+
Mutex *mutex() const
{
return m_mutex;
diff --git a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
index 29c8b92222..8844dd5624 100644
--- a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
+++ b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
@@ -67,6 +67,7 @@ private slots:
void scopeTest();
void unlockAndRelockTest();
void lockerStateTest();
+ void moveSemantics();
};
void tst_QMutexLocker::scopeTest()
@@ -214,5 +215,71 @@ void tst_QMutexLocker::lockerStateTest()
thread = nullptr;
}
+void tst_QMutexLocker::moveSemantics()
+{
+ {
+ QMutexLocker<QMutex> locker(nullptr);
+ QVERIFY(!locker.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(!locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), nullptr);
+ }
+
+ QMutex mutex;
+
+ {
+ QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+ }
+
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ {
+ QMutex mutex;
+ QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+
+ locker.unlock();
+ QVERIFY(!locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(!locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ locker2.relock();
+ QVERIFY(!locker.isLocked());
+ QVERIFY(locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+ }
+
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+}
+
QTEST_MAIN(tst_QMutexLocker)
#include "tst_qmutexlocker.moc"