Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qorderedmutexlocker_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QORDEREDMUTEXLOCKER_P_H
5#define QORDEREDMUTEXLOCKER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qglobal_p.h>
19#include <QtCore/qmutex.h>
20
21#include <functional>
22
24
25#if QT_CONFIG(thread)
26
27/*
28 Locks 2 mutexes in a defined order, avoiding a recursive lock if
29 we're trying to lock the same mutex twice.
30*/
32{
33public:
36 : mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
37 mtx2((m1 == m2) ? nullptr : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
38 locked(false)
39 {
40 relock();
41 }
42
43 Q_DISABLE_COPY(QOrderedMutexLocker)
44
45 void swap(QOrderedMutexLocker &other) noexcept
46 {
47 qSwap(this->mtx1, other.mtx1);
48 qSwap(this->mtx2, other.mtx2);
49 qSwap(this->locked, other.locked);
50 }
51
52 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QOrderedMutexLocker)
53
56 : mtx1(std::exchange(other.mtx1, nullptr))
57 , mtx2(std::exchange(other.mtx2, nullptr))
58 , locked(std::exchange(other.locked, false))
59 {}
60
62 {
63 unlock();
64 }
65
66 void relock()
67 {
68 if (!locked) {
69 if (mtx1) mtx1->lock();
70 if (mtx2) mtx2->lock();
71 locked = true;
72 }
73 }
74
84 void dismiss()
85 {
86 Q_ASSERT(locked);
87 locked = false;
88 }
89
90 void unlock()
91 {
92 if (locked) {
93 if (mtx2) mtx2->unlock();
94 if (mtx1) mtx1->unlock();
95 locked = false;
96 }
97 }
98
99 static bool relock(QBasicMutex *mtx1, QBasicMutex *mtx2)
100 {
101 // mtx1 is already locked, mtx2 not... do we need to unlock and relock?
102 if (mtx1 == mtx2)
103 return false;
104 if (std::less<QBasicMutex *>()(mtx1, mtx2)) {
105 mtx2->lock();
106 return true;
107 }
108 if (!mtx2->tryLock()) {
109 mtx1->unlock();
110 mtx2->lock();
111 mtx1->lock();
112 }
113 return true;
114 }
115
116private:
117 QBasicMutex *mtx1, *mtx2;
118 bool locked;
119};
120
121#else
122
140
141#endif
142
143
145
146#endif
\inmodule QtCore
Definition qmutex.h:281
QOrderedMutexLocker & operator=(QOrderedMutexLocker &&other)=default
Q_NODISCARD_CTOR QOrderedMutexLocker(QBasicMutex *, QBasicMutex *)
Q_NODISCARD_CTOR QOrderedMutexLocker(QOrderedMutexLocker &&)=default
static bool relock(QBasicMutex *, QBasicMutex *)
Combined button and popup list for selecting options.
#define Q_NODISCARD_CTOR
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Definition qswap.h:20
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
this swap(other)