QOrderedMutexLocker: Disable copy and provide explicit dismiss function

Copying a QOrderedMutexLocker is questionable, and would currenly easily
lead to UB. Therefore we delete the copy ctor and copy assignment
operator, and implement well-behaving move operators.
In addition, provide an explicit dismiss method for cases where we don't
want the locker to unlock the mutexes, as they have been manually
unlocked (this could have been implemented previoulsy by using the copy
assignment operator).

Change-Id: If2a888710e1c74277b28fd3e2939ab26fff0c7ae
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 7fefce73284de4204d64c7e4129f39004a13cdad)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Fabian Kosmale 2021-06-11 11:31:00 +02:00 committed by Qt Cherry-pick Bot
parent a0fa1654a7
commit 32eb742b04

View File

@ -74,6 +74,24 @@ public:
{
relock();
}
Q_DISABLE_COPY(QOrderedMutexLocker)
void swap(QOrderedMutexLocker &other) noexcept
{
qSwap(this->mtx1, other.mtx1);
qSwap(this->mtx2, other.mtx2);
qSwap(this->locked, other.locked);
}
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QOrderedMutexLocker)
QOrderedMutexLocker(QOrderedMutexLocker &&other) noexcept
: mtx1(std::exchange(other.mtx1, nullptr))
, mtx2(std::exchange(other.mtx2, nullptr))
, locked(std::exchange(other.locked, false))
{}
~QOrderedMutexLocker()
{
unlock();
@ -88,6 +106,21 @@ public:
}
}
/*!
\internal
Can be called if the mutexes have been unlocked manually, and sets the
state of the QOrderedMutexLocker to unlocked.
The caller is expected to have unlocked both of them if they
are not the same. Calling this method when the QOrderedMutexLocker is
unlocked or when the provided mutexes have not actually been unlocked is
UB.
*/
void dismiss()
{
Q_ASSERT(locked);
locked = false;
}
void unlock()
{
if (locked) {
@ -153,11 +186,15 @@ private:
class QOrderedMutexLocker
{
public:
Q_DISABLE_COPY(QOrderedMutexLocker)
QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {}
QOrderedMutexLocker(QOrderedMutexLocker &&) = default;
QOrderedMutexLocker& operator=(QOrderedMutexLocker &&other) = default;
~QOrderedMutexLocker() {}
void relock() {}
void unlock() {}
void dismiss() {}
static bool relock(QBasicMutex *, QBasicMutex *) { return false; }
};