Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
// Qt-Security score:significant reason:default
4
5
#
ifndef
QORDEREDMUTEXLOCKER_P_H
6
#
define
QORDEREDMUTEXLOCKER_P_H
7
8
//
9
// W A R N I N G
10
// -------------
11
//
12
// This file is not part of the Qt API. It exists purely as an
13
// implementation detail. This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#
include
<
QtCore
/
private
/
qglobal_p
.
h
>
20
#
include
<
QtCore
/
qmutex
.
h
>
21
22
#
include
<
functional
>
23
24
QT_BEGIN_NAMESPACE
25
26
#
if
QT_CONFIG
(
thread
)
27
28
/*
29
Locks 2 mutexes in a defined order, avoiding a recursive lock if
30
we're trying to lock the same mutex twice.
31
*/
32
class
QOrderedMutexLocker
33
{
34
public
:
35
Q_NODISCARD_CTOR
36
QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2)
37
: mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
38
mtx2((m1 == m2) ?
nullptr
: (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
39
locked(
false
)
40
{
41
relock();
42
}
43
44
Q_DISABLE_COPY(QOrderedMutexLocker)
45
46
void
swap(QOrderedMutexLocker &other)
noexcept
47
{
48
qSwap(
this
->mtx1, other.mtx1);
49
qSwap(
this
->mtx2, other.mtx2);
50
qSwap(
this
->locked, other.locked);
51
}
52
53
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QOrderedMutexLocker)
54
55
Q_NODISCARD_CTOR
56
QOrderedMutexLocker(QOrderedMutexLocker &&other)
noexcept
57
: mtx1(std::exchange(other.mtx1,
nullptr
))
58
, mtx2(std::exchange(other.mtx2,
nullptr
))
59
, locked(std::exchange(other.locked,
false
))
60
{}
61
62
~QOrderedMutexLocker()
63
{
64
unlock();
65
}
66
67
void
relock()
68
{
69
if
(!locked) {
70
if
(mtx1) mtx1->lock();
71
if
(mtx2) mtx2->lock();
72
locked =
true
;
73
}
74
}
75
76
/*!
77
\internal
78
Can be called if the mutexes have been unlocked manually, and sets the
79
state of the QOrderedMutexLocker to unlocked.
80
The caller is expected to have unlocked both of them if they
81
are not the same. Calling this method when the QOrderedMutexLocker is
82
unlocked or when the provided mutexes have not actually been unlocked is
83
UB.
84
*/
85
void
dismiss()
86
{
87
Q_ASSERT(locked);
88
locked =
false
;
89
}
90
91
void
unlock()
92
{
93
if
(locked) {
94
if
(mtx2) mtx2->unlock();
95
if
(mtx1) mtx1->unlock();
96
locked =
false
;
97
}
98
}
99
100
static
bool
relock(QBasicMutex *mtx1, QBasicMutex *mtx2)
101
{
102
// mtx1 is already locked, mtx2 not... do we need to unlock and relock?
103
if
(mtx1 == mtx2)
104
return
false
;
105
if
(std::less<QBasicMutex *>()(mtx1, mtx2)) {
106
mtx2->lock();
107
return
true
;
108
}
109
if
(!mtx2->tryLock()) {
110
mtx1->unlock();
111
mtx2->lock();
112
mtx1->lock();
113
}
114
return
true
;
115
}
116
117
private
:
118
QBasicMutex *mtx1, *mtx2;
119
bool
locked;
120
};
121
122
#
else
123
124
class
QOrderedMutexLocker
125
{
126
public
:
127
Q_DISABLE_COPY(QOrderedMutexLocker)
128
Q_NODISCARD_CTOR
129
QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {}
130
Q_NODISCARD_CTOR
131
QOrderedMutexLocker(QOrderedMutexLocker &&) =
default
;
132
QOrderedMutexLocker& operator=(QOrderedMutexLocker &&other) =
default
;
133
~QOrderedMutexLocker() {}
134
135
void
relock() {}
136
void
unlock() {}
137
void
dismiss() {}
138
139
static
bool
relock(QBasicMutex *, QBasicMutex *) {
return
false
; }
140
};
141
142
#
endif
143
144
145
QT_END_NAMESPACE
146
147
#
endif
qtbase
src
corelib
thread
qorderedmutexlocker_p.h
Generated on
for Qt by
1.18.0