QMutexLocker: add move semantics
The class is similar to unique_lock in that it allows for unlocking and relocking. Since the locked state is tracked by QMutexLocker itself, it's trivial to make it movable. [ChangeLog][QtCore][QMutexLocker] The class is now movable. Change-Id: I534044f8024575e996c12efb2236761d493798a3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
4b8c20a297
commit
20d0ff1a39
@ -485,6 +485,40 @@ void QRecursiveMutex::unlock() noexcept
|
||||
\sa QMutex::lock()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user