qreadwritelock.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qreadwritelock.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Copyright (C) 2016 Intel Corporation.-
5** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>-
6** Contact: https://www.qt.io/licensing/-
7**-
8** This file is part of the QtCore module of the Qt Toolkit.-
9**-
10** $QT_BEGIN_LICENSE:LGPL$-
11** Commercial License Usage-
12** Licensees holding valid commercial Qt licenses may use this file in-
13** accordance with the commercial license agreement provided with the-
14** Software or, alternatively, in accordance with the terms contained in-
15** a written agreement between you and The Qt Company. For licensing terms-
16** and conditions see https://www.qt.io/terms-conditions. For further-
17** information use the contact form at https://www.qt.io/contact-us.-
18**-
19** GNU Lesser General Public License Usage-
20** Alternatively, this file may be used under the terms of the GNU Lesser-
21** General Public License version 3 as published by the Free Software-
22** Foundation and appearing in the file LICENSE.LGPL3 included in the-
23** packaging of this file. Please review the following information to-
24** ensure the GNU Lesser General Public License version 3 requirements-
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
26**-
27** GNU General Public License Usage-
28** Alternatively, this file may be used under the terms of the GNU-
29** General Public License version 2.0 or (at your option) the GNU General-
30** Public license version 3 or any later version approved by the KDE Free-
31** Qt Foundation. The licenses are as published by the Free Software-
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
33** included in the packaging of this file. Please review the following-
34** information to ensure the GNU General Public License requirements will-
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
36** https://www.gnu.org/licenses/gpl-3.0.html.-
37**-
38** $QT_END_LICENSE$-
39**-
40****************************************************************************/-
41-
42#include "qplatformdefs.h"-
43#include "qreadwritelock.h"-
44-
45#ifndef QT_NO_THREAD-
46#include "qmutex.h"-
47#include "qthread.h"-
48#include "qwaitcondition.h"-
49#include "qreadwritelock_p.h"-
50#include "qelapsedtimer.h"-
51#include "private/qfreelist_p.h"-
52-
53QT_BEGIN_NAMESPACE-
54-
55/*-
56 * Implementation details of QReadWriteLock:-
57 *-
58 * Depending on the valued of d_ptr, the lock is in the following state:-
59 * - when d_ptr == 0x0: Unlocked (no readers, no writers) and non-recursive.-
60 * - when d_ptr & 0x1: If the least significant bit is set, we are locked for read.-
61 * In that case, d_ptr>>4 represents the number of reading threads minus 1. No writers-
62 * are waiting, and the lock is not recursive.-
63 * - when d_ptr == 0x2: We are locked for write and nobody is waiting. (no contention)-
64 * - In any other case, d_ptr points to an actual QReadWriteLockPrivate.-
65 */-
66-
67namespace {-
68enum {-
69 StateMask = 0x3,-
70 StateLockedForRead = 0x1,-
71 StateLockedForWrite = 0x2,-
72};-
73const auto dummyLockedForRead = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForRead));-
74const auto dummyLockedForWrite = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForWrite));-
75inline bool isUncontendedLocked(const QReadWriteLockPrivate *d)-
76{
executed 317361 times by 523 tests: return quintptr(d) & StateMask;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • tst_QDBusConnection_NoApplication
  • tst_QDBusConnection_SpyHook
  • tst_QDBusServiceWatcher
  • tst_QDBusThreading
  • tst_QDirIterator
  • tst_QFile
  • tst_QGlobalStatic
  • tst_QMetaType
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_collections - unknown status
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • tst_largefile - unknown status
  • tst_modeltest - unknown status
  • tst_networkselftest - unknown status
  • tst_platformsocketengine - unknown status
  • tst_q_func_info - unknown status
  • ...
return quintptr(d) & StateMask; }
executed 317361 times by 523 tests: return quintptr(d) & StateMask;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • tst_QDBusConnection_NoApplication
  • tst_QDBusConnection_SpyHook
  • tst_QDBusServiceWatcher
  • tst_QDBusThreading
  • tst_QDirIterator
  • tst_QFile
  • tst_QGlobalStatic
  • tst_QMetaType
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_collections - unknown status
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • tst_largefile - unknown status
  • tst_modeltest - unknown status
  • tst_networkselftest - unknown status
  • tst_platformsocketengine - unknown status
  • tst_q_func_info - unknown status
  • ...
317361
77}-
78-
79/*! \class QReadWriteLock-
80 \inmodule QtCore-
81 \brief The QReadWriteLock class provides read-write locking.-
82-
83 \threadsafe-
84-
85 \ingroup thread-
86-
87 A read-write lock is a synchronization tool for protecting-
88 resources that can be accessed for reading and writing. This type-
89 of lock is useful if you want to allow multiple threads to have-
90 simultaneous read-only access, but as soon as one thread wants to-
91 write to the resource, all other threads must be blocked until-
92 the writing is complete.-
93-
94 In many cases, QReadWriteLock is a direct competitor to QMutex.-
95 QReadWriteLock is a good choice if there are many concurrent-
96 reads and writing occurs infrequently.-
97-
98 Example:-
99-
100 \snippet code/src_corelib_thread_qreadwritelock.cpp 0-
101-
102 To ensure that writers aren't blocked forever by readers, readers-
103 attempting to obtain a lock will not succeed if there is a blocked-
104 writer waiting for access, even if the lock is currently only-
105 accessed by other readers. Also, if the lock is accessed by a-
106 writer and another writer comes in, that writer will have-
107 priority over any readers that might also be waiting.-
108-
109 Like QMutex, a QReadWriteLock can be recursively locked by the-
110 same thread when constructed with \l{QReadWriteLock::Recursive} as-
111 \l{QReadWriteLock::RecursionMode}. In such cases,-
112 unlock() must be called the same number of times lockForWrite() or-
113 lockForRead() was called. Note that the lock type cannot be-
114 changed when trying to lock recursively, i.e. it is not possible-
115 to lock for reading in a thread that already has locked for-
116 writing (and vice versa).-
117-
118 \sa QReadLocker, QWriteLocker, QMutex, QSemaphore-
119*/-
120-
121/*!-
122 \enum QReadWriteLock::RecursionMode-
123 \since 4.4-
124-
125 \value Recursive In this mode, a thread can lock the same-
126 QReadWriteLock multiple times. The QReadWriteLock won't be unlocked-
127 until a corresponding number of unlock() calls have been made.-
128-
129 \value NonRecursive In this mode, a thread may only lock a-
130 QReadWriteLock once.-
131-
132 \sa QReadWriteLock()-
133*/-
134-
135/*!-
136 \since 4.4-
137-
138 Constructs a QReadWriteLock object in the given \a recursionMode.-
139-
140 The default recursion mode is NonRecursive.-
141-
142 \sa lockForRead(), lockForWrite(), RecursionMode-
143*/-
144QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)-
145 : d_ptr(recursionMode == Recursive ? new QReadWriteLockPrivate(true) : nullptr)-
146{-
147 Q_ASSERT_X(!(quintptr(d_ptr.load()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");-
148}
executed 42232 times by 296 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • ...
42232
149-
150/*!-
151 Destroys the QReadWriteLock object.-
152-
153 \warning Destroying a read-write lock that is in use may result-
154 in undefined behavior.-
155*/-
156QReadWriteLock::~QReadWriteLock()-
157{-
158 auto d = d_ptr.load();-
159 if (isUncontendedLocked(d)) {
isUncontendedLocked(d)Description
TRUEnever evaluated
FALSEevaluated 43112 times by 519 tests
Evaluated by:
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • tst_QDBusConnection_NoApplication
  • tst_QDBusConnection_SpyHook
  • tst_QDBusServiceWatcher
  • tst_QDBusThreading
  • tst_QGlobalStatic
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_collections - unknown status
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • tst_largefile - unknown status
  • tst_modeltest - unknown status
  • tst_networkselftest - unknown status
  • tst_platformsocketengine - unknown status
  • tst_q_func_info - unknown status
  • tst_qabstractanimation - unknown status
  • tst_qabstractbutton - unknown status
  • tst_qabstractfileengine - unknown status
  • tst_qabstractitemmodel - unknown status
  • ...
0-43112
160 qWarning("QReadWriteLock: destroying locked QReadWriteLock");-
161 return;
never executed: return;
0
162 }-
163 delete d;-
164}
executed 43112 times by 519 tests: end of block
Executed by:
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • tst_QDBusConnection_NoApplication
  • tst_QDBusConnection_SpyHook
  • tst_QDBusServiceWatcher
  • tst_QDBusThreading
  • tst_QGlobalStatic
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_collections - unknown status
  • tst_compiler - unknown status
  • tst_gestures - unknown status
  • tst_lancelot - unknown status
  • tst_languagechange - unknown status
  • tst_largefile - unknown status
  • tst_modeltest - unknown status
  • tst_networkselftest - unknown status
  • tst_platformsocketengine - unknown status
  • tst_q_func_info - unknown status
  • tst_qabstractanimation - unknown status
  • tst_qabstractbutton - unknown status
  • tst_qabstractfileengine - unknown status
  • tst_qabstractitemmodel - unknown status
  • ...
43112
165-
166/*!-
167 Locks the lock for reading. This function will block the current-
168 thread if another thread has locked for writing.-
169-
170 It is not possible to lock for read if the thread already has-
171 locked for write.-
172-
173 \sa unlock(), lockForWrite(), tryLockForRead()-
174*/-
175void QReadWriteLock::lockForRead()-
176{-
177 if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead))
d_ptr.testAndS...LockedForRead)Description
TRUEevaluated 1557572 times by 355 tests
Evaluated by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • ...
FALSEevaluated 143670 times by 10 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_Spdy
143670-1557572
178 return;
executed 1557572 times by 355 tests: return;
Executed by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • ...
1557572
179 tryLockForRead(-1);-
180}
executed 143670 times by 10 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_Spdy
143670
181-
182/*!-
183 Attempts to lock for reading. If the lock was obtained, this-
184 function returns \c true, otherwise it returns \c false instead of-
185 waiting for the lock to become available, i.e. it does not block.-
186-
187 The lock attempt will fail if another thread has locked for-
188 writing.-
189-
190 If the lock was obtained, the lock must be unlocked with unlock()-
191 before another thread can successfully lock it for writing.-
192-
193 It is not possible to lock for read if the thread already has-
194 locked for write.-
195-
196 \sa unlock(), lockForRead()-
197*/-
198bool QReadWriteLock::tryLockForRead()-
199{-
200 return tryLockForRead(0);
executed 43 times by 2 tests: return tryLockForRead(0);
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
43
201}-
202-
203/*! \overload-
204-
205 Attempts to lock for reading. This function returns \c true if the-
206 lock was obtained; otherwise it returns \c false. If another thread-
207 has locked for writing, this function will wait for at most \a-
208 timeout milliseconds for the lock to become available.-
209-
210 Note: Passing a negative number as the \a timeout is equivalent to-
211 calling lockForRead(), i.e. this function will wait forever until-
212 lock can be locked for reading when \a timeout is negative.-
213-
214 If the lock was obtained, the lock must be unlocked with unlock()-
215 before another thread can successfully lock it for writing.-
216-
217 It is not possible to lock for read if the thread already has-
218 locked for write.-
219-
220 \sa unlock(), lockForRead()-
221*/-
222bool QReadWriteLock::tryLockForRead(int timeout)-
223{-
224 // Fast case: non contended:-
225 QReadWriteLockPrivate *d;-
226 if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d))
d_ptr.testAndS...kedForRead, d)Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 143712 times by 10 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_Spdy
4-143712
227 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_QReadWriteLock
4
228-
229 while (true) {-
230 if (d == 0) {
d == 0Description
TRUEnever evaluated
FALSEevaluated 143712 times by 10 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_Spdy
0-143712
231 if (!d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d))
!d_ptr.testAnd...kedForRead, d)Description
TRUEnever evaluated
FALSEnever evaluated
0
232 continue;
never executed: continue;
0
233 return true;
never executed: return true;
0
234 }-
235-
236 if ((quintptr(d) & StateMask) == StateLockedForRead) {
(quintptr(d) &...eLockedForReadDescription
TRUEevaluated 11198 times by 6 tests
Evaluated by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
FALSEevaluated 132514 times by 6 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
11198-132514
237 // locked for read, increase the counter-
238 const auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) + (1U<<4));-
239 Q_ASSERT_X(quintptr(val) > (1U<<4), "QReadWriteLock::tryLockForRead()",-
240 "Overflow in lock counter");-
241 if (!d_ptr.testAndSetAcquire(d, val, d))
!d_ptr.testAnd...ire(d, val, d)Description
TRUEnever evaluated
FALSEevaluated 11198 times by 6 tests
Evaluated by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
0-11198
242 continue;
never executed: continue;
0
243 return true;
executed 11198 times by 6 tests: return true;
Executed by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
11198
244 }-
245-
246 if (d == dummyLockedForWrite) {
d == dummyLockedForWriteDescription
TRUEevaluated 42 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 132472 times by 6 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
42-132472
247 if (!timeout)
!timeoutDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 40 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
2-40
248 return false;
executed 2 times by 1 test: return false;
Executed by:
  • tst_QReadWriteLock
2
249-
250 // locked for write, assign a d_ptr and wait.-
251 auto val = QReadWriteLockPrivate::allocate();-
252 val->writerCount = 1;-
253 if (!d_ptr.testAndSetOrdered(d, val, d)) {
!d_ptr.testAnd...red(d, val, d)Description
TRUEnever evaluated
FALSEevaluated 40 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
0-40
254 val->writerCount = 0;-
255 val->release();-
256 continue;
never executed: continue;
0
257 }-
258 d = val;-
259 }
executed 40 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
40
260 Q_ASSERT(!isUncontendedLocked(d));-
261 // d is an actual pointer;-
262-
263 if (d->recursive)
d->recursiveDescription
TRUEevaluated 126 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 132386 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
126-132386
264 return d->recursiveLockForRead(timeout);
executed 126 times by 5 tests: return d->recursiveLockForRead(timeout);
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
126
265-
266 QMutexLocker lock(&d->mutex);-
267 if (d != d_ptr.load()) {
d != d_ptr.load()Description
TRUEnever evaluated
FALSEevaluated 132386 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
0-132386
268 // d_ptr has changed: this QReadWriteLock was unlocked before we had-
269 // time to lock d->mutex.-
270 // We are holding a lock to a mutex within a QReadWriteLockPrivate-
271 // that is already released (or even is already re-used). That's ok-
272 // because the QFreeList never frees them.-
273 // Just unlock d->mutex (at the end of the scope) and retry.-
274 d = d_ptr.loadAcquire();-
275 continue;
never executed: continue;
0
276 }-
277 return d->lockForRead(timeout);
executed 132386 times by 3 tests: return d->lockForRead(timeout);
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
132386
278 }-
279}
never executed: end of block
0
280-
281/*!-
282 Locks the lock for writing. This function will block the current-
283 thread if another thread (including the current) has locked for-
284 reading or writing (unless the lock has been created using the-
285 \l{QReadWriteLock::Recursive} mode).-
286-
287 It is not possible to lock for write if the thread already has-
288 locked for read.-
289-
290 \sa unlock(), lockForRead(), tryLockForWrite()-
291*/-
292void QReadWriteLock::lockForWrite()-
293{-
294 tryLockForWrite(-1);-
295}
executed 348346 times by 568 tests: end of block
Executed by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • ...
348346
296-
297/*!-
298 Attempts to lock for writing. If the lock was obtained, this-
299 function returns \c true; otherwise, it returns \c false immediately.-
300-
301 The lock attempt will fail if another thread has locked for-
302 reading or writing.-
303-
304 If the lock was obtained, the lock must be unlocked with unlock()-
305 before another thread can successfully lock it.-
306-
307 It is not possible to lock for write if the thread already has-
308 locked for read.-
309-
310 \sa unlock(), lockForWrite()-
311*/-
312bool QReadWriteLock::tryLockForWrite()-
313{-
314 return tryLockForWrite(0);
executed 62 times by 4 tests: return tryLockForWrite(0);
Executed by:
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
62
315}-
316-
317/*! \overload-
318-
319 Attempts to lock for writing. This function returns \c true if the-
320 lock was obtained; otherwise it returns \c false. If another thread-
321 has locked for reading or writing, this function will wait for at-
322 most \a timeout milliseconds for the lock to become available.-
323-
324 Note: Passing a negative number as the \a timeout is equivalent to-
325 calling lockForWrite(), i.e. this function will wait forever until-
326 lock can be locked for writing when \a timeout is negative.-
327-
328 If the lock was obtained, the lock must be unlocked with unlock()-
329 before another thread can successfully lock it.-
330-
331 It is not possible to lock for write if the thread already has-
332 locked for read.-
333-
334 \sa unlock(), lockForWrite()-
335*/-
336bool QReadWriteLock::tryLockForWrite(int timeout)-
337{-
338 // Fast case: non contended:-
339 QReadWriteLockPrivate *d;-
340 if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForWrite, d))
d_ptr.testAndS...edForWrite, d)Description
TRUEevaluated 345353 times by 565 tests
Evaluated by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • tst_QBoxLayout
  • ...
FALSEevaluated 3057 times by 11 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
3057-345353
341 return true;
executed 345353 times by 565 tests: return true;
Executed by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • tst_QBoxLayout
  • ...
345353
342-
343 while (true) {-
344 if (d == 0) {
d == 0Description
TRUEnever evaluated
FALSEevaluated 3057 times by 11 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
0-3057
345 if (!d_ptr.testAndSetAcquire(d, dummyLockedForWrite, d))
!d_ptr.testAnd...edForWrite, d)Description
TRUEnever evaluated
FALSEnever evaluated
0
346 continue;
never executed: continue;
0
347 return true;
never executed: return true;
0
348 }-
349-
350 if (isUncontendedLocked(d)) {
isUncontendedLocked(d)Description
TRUEevaluated 88 times by 5 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_QWriteLocker
FALSEevaluated 2969 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
88-2969
351 if (!timeout)
!timeoutDescription
TRUEevaluated 10 times by 3 tests
Evaluated by:
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWriteLocker
FALSEevaluated 78 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
10-78
352 return false;
executed 10 times by 3 tests: return false;
Executed by:
  • tst_QReadLocker
  • tst_QReadWriteLock
  • tst_QWriteLocker
10
353-
354 // locked for either read or write, assign a d_ptr and wait.-
355 auto val = QReadWriteLockPrivate::allocate();-
356 if (d == dummyLockedForWrite)
d == dummyLockedForWriteDescription
TRUEevaluated 54 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 24 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
24-54
357 val->writerCount = 1;
executed 54 times by 3 tests: val->writerCount = 1;
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
54
358 else-
359 val->readerCount = (quintptr(d) >> 4) + 1;
executed 24 times by 3 tests: val->readerCount = (quintptr(d) >> 4) + 1;
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
24
360 if (!d_ptr.testAndSetOrdered(d, val, d)) {
!d_ptr.testAnd...red(d, val, d)Description
TRUEnever evaluated
FALSEevaluated 78 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
0-78
361 val->writerCount = val->readerCount = 0;-
362 val->release();-
363 continue;
never executed: continue;
0
364 }-
365 d = val;-
366 }
executed 78 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
78
367 Q_ASSERT(!isUncontendedLocked(d));-
368 // d is an actual pointer;-
369-
370 if (d->recursive)
d->recursiveDescription
TRUEevaluated 76 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
FALSEevaluated 2971 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
76-2971
371 return d->recursiveLockForWrite(timeout);
executed 76 times by 8 tests: return d->recursiveLockForWrite(timeout);
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
76
372-
373 QMutexLocker lock(&d->mutex);-
374 if (d != d_ptr.load()) {
d != d_ptr.load()Description
TRUEnever evaluated
FALSEevaluated 2971 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
0-2971
375 // The mutex was unlocked before we had time to lock the mutex.-
376 // We are holding to a mutex within a QReadWriteLockPrivate that is already released-
377 // (or even is already re-used) but that's ok because the QFreeList never frees them.-
378 d = d_ptr.loadAcquire();-
379 continue;
never executed: continue;
0
380 }-
381 return d->lockForWrite(timeout);
executed 2971 times by 3 tests: return d->lockForWrite(timeout);
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
2971
382 }-
383}
never executed: end of block
0
384-
385/*!-
386 Unlocks the lock.-
387-
388 Attempting to unlock a lock that is not locked is an error, and will result-
389 in program termination.-
390-
391 \sa lockForRead(), lockForWrite(), tryLockForRead(), tryLockForWrite()-
392*/-
393void QReadWriteLock::unlock()-
394{-
395 QReadWriteLockPrivate *d = d_ptr.load();-
396 while (true) {-
397 Q_ASSERT_X(d, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock");-
398-
399 // Fast case: no contention: (no waiters, no other readers)-
400 if (quintptr(d) <= 2) { // 1 or 2 (StateLockedForRead or StateLockedForWrite)
quintptr(d) <= 2Description
TRUEevaluated 1902811 times by 572 tests
Evaluated by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • ...
FALSEevaluated 146830 times by 13 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_Spdy
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
146830-1902811
401 if (!d_ptr.testAndSetRelease(d, nullptr, d))
!d_ptr.testAnd...d, nullptr, d)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 1902810 times by 572 tests
Evaluated by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • ...
1-1902810
402 continue;
executed 1 time by 1 test: continue;
Executed by:
  • tst_QReadWriteLock
1
403 return;
executed 1902810 times by 572 tests: return;
Executed by:
  • tst_Gestures
  • tst_Lancelot
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • tst_QAnimationGroup
  • tst_QApplication
  • tst_QArrayData
  • tst_QArrayData_StrictIterators
  • tst_QAsn1Element
  • tst_QBackingStore
  • ...
1902810
404 }-
405-
406 if ((quintptr(d) & StateMask) == StateLockedForRead) {
(quintptr(d) &...eLockedForReadDescription
TRUEevaluated 11197 times by 6 tests
Evaluated by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
FALSEevaluated 135633 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
11197-135633
407 Q_ASSERT(quintptr(d) > (1U<<4)); //otherwise that would be the fast case-
408 // Just decrease the reader's count.-
409 auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) - (1U<<4));-
410 if (!d_ptr.testAndSetRelease(d, val, d))
!d_ptr.testAnd...ase(d, val, d)Description
TRUEnever evaluated
FALSEevaluated 11197 times by 6 tests
Evaluated by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
0-11197
411 continue;
never executed: continue;
0
412 return;
executed 11197 times by 6 tests: return;
Executed by:
  • tst_QGuiEventLoop
  • tst_QHostInfo
  • tst_QMetaType
  • tst_QNetworkReply
  • tst_QReadWriteLock
  • tst_Spdy
11197
413 }-
414-
415 Q_ASSERT(!isUncontendedLocked(d));-
416-
417 if (d->recursive) {
d->recursiveDescription
TRUEevaluated 159 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
FALSEevaluated 135474 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
159-135474
418 d->recursiveUnlock();-
419 return;
executed 159 times by 8 tests: return;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
159
420 }-
421-
422 QMutexLocker locker(&d->mutex);-
423 if (d->writerCount) {
d->writerCountDescription
TRUEevaluated 3064 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 132410 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
3064-132410
424 Q_ASSERT(d->writerCount == 1);-
425 Q_ASSERT(d->readerCount == 0);-
426 d->writerCount = 0;-
427 } else {
executed 3064 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
3064
428 Q_ASSERT(d->readerCount > 0);-
429 d->readerCount--;-
430 if (d->readerCount > 0)
d->readerCount > 0Description
TRUEevaluated 132145 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 265 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
265-132145
431 return;
executed 132145 times by 1 test: return;
Executed by:
  • tst_QReadWriteLock
132145
432 }
executed 265 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
265
433-
434 if (d->waitingReaders || d->waitingWriters) {
d->waitingReadersDescription
TRUEevaluated 327 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 3002 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
d->waitingWritersDescription
TRUEevaluated 2884 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 118 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
118-3002
435 d->unlock();-
436 } else {
executed 3211 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
3211
437 Q_ASSERT(d_ptr.load() == d); // should not change when we still hold the mutex-
438 d_ptr.storeRelease(nullptr);-
439 d->release();-
440 }
executed 118 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
118
441 return;
executed 3329 times by 3 tests: return;
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
3329
442 }-
443}
never executed: end of block
0
444-
445/*! \internal Helper for QWaitCondition::wait */-
446QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const-
447{-
448 QReadWriteLockPrivate *d = d_ptr.load();-
449 switch (quintptr(d) & StateMask) {-
450 case StateLockedForRead: return LockedForRead;
executed 25 times by 1 test: return LockedForRead;
Executed by:
  • tst_QWaitCondition
executed 25 times by 1 test: case StateLockedForRead:
Executed by:
  • tst_QWaitCondition
25
451 case StateLockedForWrite: return LockedForWrite;
executed 108 times by 1 test: return LockedForWrite;
Executed by:
  • tst_QWaitCondition
executed 108 times by 1 test: case StateLockedForWrite:
Executed by:
  • tst_QWaitCondition
108
452 }-
453-
454 if (!d)
!dDescription
TRUEnever evaluated
FALSEevaluated 141 times by 1 test
Evaluated by:
  • tst_QWaitCondition
0-141
455 return Unlocked;
never executed: return Unlocked;
0
456 if (d->writerCount > 1)
d->writerCount > 1Description
TRUEnever evaluated
FALSEevaluated 141 times by 1 test
Evaluated by:
  • tst_QWaitCondition
0-141
457 return RecursivelyLocked;
never executed: return RecursivelyLocked;
0
458 else if (d->writerCount == 1)
d->writerCount == 1Description
TRUEevaluated 123 times by 1 test
Evaluated by:
  • tst_QWaitCondition
FALSEevaluated 18 times by 1 test
Evaluated by:
  • tst_QWaitCondition
18-123
459 return LockedForWrite;
executed 123 times by 1 test: return LockedForWrite;
Executed by:
  • tst_QWaitCondition
123
460 return LockedForRead;
executed 18 times by 1 test: return LockedForRead;
Executed by:
  • tst_QWaitCondition
18
461-
462}-
463-
464bool QReadWriteLockPrivate::lockForRead(int timeout)-
465{-
466 Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function-
467-
468 QElapsedTimer t;-
469 if (timeout > 0)
timeout > 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 132492 times by 6 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
1-132492
470 t.start();
executed 1 time by 1 test: t.start();
Executed by:
  • tst_QReadWriteLock
1
471-
472 while (waitingWriters || writerCount) {
waitingWritersDescription
TRUEevaluated 386 times by 2 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
FALSEevaluated 132543 times by 6 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
writerCountDescription
TRUEevaluated 72 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 132471 times by 6 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
72-132543
473 if (timeout == 0)
timeout == 0Description
TRUEevaluated 21 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 437 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
21-437
474 return false;
executed 21 times by 2 tests: return false;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
21
475 if (timeout > 0) {
timeout > 0Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 429 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
8-429
476 auto elapsed = t.elapsed();-
477 if (elapsed > timeout)
elapsed > timeoutDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 7 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
1-7
478 return false;
executed 1 time by 1 test: return false;
Executed by:
  • tst_QReadWriteLock
1
479 waitingReaders++;-
480 readerCond.wait(&mutex, timeout - elapsed);-
481 } else {
executed 7 times by 1 test: end of block
Executed by:
  • tst_QReadWriteLock
7
482 waitingReaders++;-
483 readerCond.wait(&mutex);-
484 }
executed 429 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
429
485 waitingReaders--;-
486 }
executed 436 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
436
487 readerCount++;-
488 Q_ASSERT(writerCount == 0);-
489 return true;
executed 132471 times by 6 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
132471
490}-
491-
492bool QReadWriteLockPrivate::lockForWrite(int timeout)-
493{-
494 Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function-
495-
496 QElapsedTimer t;-
497 if (timeout > 0)
timeout > 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 3034 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
1-3034
498 t.start();
executed 1 time by 1 test: t.start();
Executed by:
  • tst_QReadWriteLock
1
499-
500 while (readerCount || writerCount) {
readerCountDescription
TRUEevaluated 74 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 3276 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
writerCountDescription
TRUEevaluated 264 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 3012 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
74-3276
501 if (timeout == 0)
timeout == 0Description
TRUEevaluated 22 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 316 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
22-316
502 return false;
executed 22 times by 2 tests: return false;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
22
503 if (timeout > 0) {
timeout > 0Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 308 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
8-308
504 auto elapsed = t.elapsed();-
505 if (elapsed > timeout) {
elapsed > timeoutDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
FALSEevaluated 7 times by 1 test
Evaluated by:
  • tst_QReadWriteLock
1-7
506 if (waitingReaders && !waitingWriters && !writerCount) {
waitingReadersDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tst_QReadWriteLock
!waitingWritersDescription
TRUEnever evaluated
FALSEnever evaluated
!writerCountDescription
TRUEnever evaluated
FALSEnever evaluated
0-1
507 // We timed out and now there is no more writers or waiting writers, but some-
508 // readers were queueud (probably because of us). Wake the waiting readers.-
509 readerCond.wakeAll();-
510 }
never executed: end of block
0
511 return false;
executed 1 time by 1 test: return false;
Executed by:
  • tst_QReadWriteLock
1
512 }-
513 waitingWriters++;-
514 writerCond.wait(&mutex, timeout - elapsed);-
515 } else {
executed 7 times by 1 test: end of block
Executed by:
  • tst_QReadWriteLock
7
516 waitingWriters++;-
517 writerCond.wait(&mutex);-
518 }
executed 308 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
308
519 waitingWriters--;-
520 }
executed 315 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
315
521-
522 Q_ASSERT(writerCount == 0);-
523 Q_ASSERT(readerCount == 0);-
524 writerCount = 1;-
525 return true;
executed 3012 times by 9 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
3012
526}-
527-
528void QReadWriteLockPrivate::unlock()-
529{-
530 Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function-
531 if (waitingWriters)
waitingWritersDescription
TRUEevaluated 2922 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 417 times by 9 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
417-2922
532 writerCond.wakeOne();
executed 2922 times by 3 tests: writerCond.wakeOne();
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
2922
533 else if (waitingReaders)
waitingReadersDescription
TRUEevaluated 290 times by 3 tests
Evaluated by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 127 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
127-290
534 readerCond.wakeAll();
executed 290 times by 3 tests: readerCond.wakeAll();
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
290
535}
executed 3339 times by 9 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
3339
536-
537bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)-
538{-
539 Q_ASSERT(recursive);-
540 QMutexLocker lock(&mutex);-
541-
542 Qt::HANDLE self = QThread::currentThreadId();-
543-
544 auto it = currentReaders.find(self);-
545 if (it != currentReaders.end()) {
it != currentReaders.end()Description
TRUEevaluated 19 times by 4 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 107 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
19-107
546 ++it.value();-
547 return true;
executed 19 times by 4 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
19
548 }-
549-
550 if (!lockForRead(timeout))
!lockForRead(timeout)Description
TRUEevaluated 21 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 86 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
21-86
551 return false;
executed 21 times by 2 tests: return false;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
21
552-
553 currentReaders.insert(self, 1);-
554 return true;
executed 86 times by 5 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
86
555}-
556-
557bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)-
558{-
559 Q_ASSERT(recursive);-
560 QMutexLocker lock(&mutex);-
561-
562 Qt::HANDLE self = QThread::currentThreadId();-
563 if (currentWriter == self) {
currentWriter == selfDescription
TRUEevaluated 12 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 64 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
12-64
564 writerCount++;-
565 return true;
executed 12 times by 2 tests: return true;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
12
566 }-
567-
568 if (!lockForWrite(timeout))
!lockForWrite(timeout)Description
TRUEevaluated 22 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 42 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
22-42
569 return false;
executed 22 times by 2 tests: return false;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
22
570-
571 currentWriter = self;-
572 return true;
executed 42 times by 8 tests: return true;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
42
573}-
574-
575void QReadWriteLockPrivate::recursiveUnlock()-
576{-
577 Q_ASSERT(recursive);-
578 QMutexLocker lock(&mutex);-
579-
580 Qt::HANDLE self = QThread::currentThreadId();-
581 if (self == currentWriter) {
self == currentWriterDescription
TRUEevaluated 54 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
FALSEevaluated 105 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
54-105
582 if (--writerCount > 0)
--writerCount > 0Description
TRUEevaluated 12 times by 2 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 42 times by 8 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
12-42
583 return;
executed 12 times by 2 tests: return;
Executed by:
  • tst_QReadWriteLock
  • tst_QWaitCondition
12
584 currentWriter = 0;-
585 } else {
executed 42 times by 8 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
42
586 auto it = currentReaders.find(self);-
587 if (it == currentReaders.end()) {
it == currentReaders.end()Description
TRUEnever evaluated
FALSEevaluated 105 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
0-105
588 qWarning("QReadWriteLock::unlock: unlocking from a thread that did not lock");-
589 return;
never executed: return;
0
590 } else {-
591 if (--it.value() <= 0) {
--it.value() <= 0Description
TRUEevaluated 86 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 19 times by 4 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
19-86
592 currentReaders.erase(it);-
593 readerCount--;-
594 }
executed 86 times by 5 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
86
595 if (readerCount)
readerCountDescription
TRUEevaluated 19 times by 4 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
FALSEevaluated 86 times by 5 tests
Evaluated by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
19-86
596 return;
executed 19 times by 4 tests: return;
Executed by:
  • tst_QAbstractFileEngine
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
19
597 }
executed 86 times by 5 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
86
598 }-
599-
600 unlock();-
601}
executed 128 times by 8 tests: end of block
Executed by:
  • tst_QAbstractFileEngine
  • tst_QDirIterator
  • tst_QFile
  • tst_QReadWriteLock
  • tst_QWaitCondition
  • tst_qabstractfileengine - unknown status
  • tst_qdiriterator - unknown status
  • tst_qfile - unknown status
128
602-
603// The freelist management-
604namespace {-
605struct FreeListConstants : QFreeListDefaultConstants {-
606 enum { BlockCount = 4, MaxIndex=0xffff };-
607 static const int Sizes[BlockCount];-
608};-
609const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {-
610 16,-
611 128,-
612 1024,-
613 FreeListConstants::MaxIndex - (16 + 128 + 1024)-
614};-
615-
616typedef QFreeList<QReadWriteLockPrivate, FreeListConstants> FreeList;-
617Q_GLOBAL_STATIC(FreeList, freelist);
executed 3 times by 3 tests: end of block
Executed by:
  • tst_qmetatype - unknown status
  • tst_qreadwritelock - unknown status
  • tst_qwaitcondition - unknown status
executed 3 times by 3 tests: guard.store(QtGlobalStatic::Destroyed);
Executed by:
  • tst_qmetatype - unknown status
  • tst_qreadwritelock - unknown status
  • tst_qwaitcondition - unknown status
executed 354 times by 3 tests: return &holder.value;
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
guard.load() =...c::InitializedDescription
TRUEevaluated 3 times by 3 tests
Evaluated by:
  • tst_qmetatype - unknown status
  • tst_qreadwritelock - unknown status
  • tst_qwaitcondition - unknown status
FALSEnever evaluated
0-354
618}-
619-
620QReadWriteLockPrivate *QReadWriteLockPrivate::allocate()-
621{-
622 int i = freelist->next();-
623 QReadWriteLockPrivate *d = &(*freelist)[i];-
624 d->id = i;-
625 Q_ASSERT(!d->recursive);-
626 Q_ASSERT(!d->waitingReaders && !d->waitingReaders && !d->readerCount && !d->writerCount);-
627 return d;
executed 118 times by 3 tests: return d;
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
118
628}-
629-
630void QReadWriteLockPrivate::release()-
631{-
632 Q_ASSERT(!recursive);-
633 Q_ASSERT(!waitingReaders && !waitingReaders && !readerCount && !writerCount);-
634 freelist->release(id);-
635}
executed 118 times by 3 tests: end of block
Executed by:
  • tst_QMetaType
  • tst_QReadWriteLock
  • tst_QWaitCondition
118
636-
637/*!-
638 \class QReadLocker-
639 \inmodule QtCore-
640 \brief The QReadLocker class is a convenience class that-
641 simplifies locking and unlocking read-write locks for read access.-
642-
643 \threadsafe-
644-
645 \ingroup thread-
646-
647 The purpose of QReadLocker (and QWriteLocker) is to simplify-
648 QReadWriteLock locking and unlocking. Locking and unlocking-
649 statements or in exception handling code is error-prone and-
650 difficult to debug. QReadLocker can be used in such situations-
651 to ensure that the state of the lock is always well-defined.-
652-
653 Here's an example that uses QReadLocker to lock and unlock a-
654 read-write lock for reading:-
655-
656 \snippet code/src_corelib_thread_qreadwritelock.cpp 1-
657-
658 It is equivalent to the following code:-
659-
660 \snippet code/src_corelib_thread_qreadwritelock.cpp 2-
661-
662 The QMutexLocker documentation shows examples where the use of a-
663 locker object greatly simplifies programming.-
664-
665 \sa QWriteLocker, QReadWriteLock-
666*/-
667-
668/*!-
669 \fn QReadLocker::QReadLocker(QReadWriteLock *lock)-
670-
671 Constructs a QReadLocker and locks \a lock for reading. The lock-
672 will be unlocked when the QReadLocker is destroyed. If \c lock is-
673 zero, QReadLocker does nothing.-
674-
675 \sa QReadWriteLock::lockForRead()-
676*/-
677-
678/*!-
679 \fn QReadLocker::~QReadLocker()-
680-
681 Destroys the QReadLocker and unlocks the lock that was passed to-
682 the constructor.-
683-
684 \sa QReadWriteLock::unlock()-
685*/-
686-
687/*!-
688 \fn void QReadLocker::unlock()-
689-
690 Unlocks the lock associated with this locker.-
691-
692 \sa QReadWriteLock::unlock()-
693*/-
694-
695/*!-
696 \fn void QReadLocker::relock()-
697-
698 Relocks an unlocked lock.-
699-
700 \sa unlock()-
701*/-
702-
703/*!-
704 \fn QReadWriteLock *QReadLocker::readWriteLock() const-
705-
706 Returns a pointer to the read-write lock that was passed-
707 to the constructor.-
708*/-
709-
710/*!-
711 \class QWriteLocker-
712 \inmodule QtCore-
713 \brief The QWriteLocker class is a convenience class that-
714 simplifies locking and unlocking read-write locks for write access.-
715-
716 \threadsafe-
717-
718 \ingroup thread-
719-
720 The purpose of QWriteLocker (and QReadLocker) is to simplify-
721 QReadWriteLock locking and unlocking. Locking and unlocking-
722 statements or in exception handling code is error-prone and-
723 difficult to debug. QWriteLocker can be used in such situations-
724 to ensure that the state of the lock is always well-defined.-
725-
726 Here's an example that uses QWriteLocker to lock and unlock a-
727 read-write lock for writing:-
728-
729 \snippet code/src_corelib_thread_qreadwritelock.cpp 3-
730-
731 It is equivalent to the following code:-
732-
733 \snippet code/src_corelib_thread_qreadwritelock.cpp 4-
734-
735 The QMutexLocker documentation shows examples where the use of a-
736 locker object greatly simplifies programming.-
737-
738 \sa QReadLocker, QReadWriteLock-
739*/-
740-
741/*!-
742 \fn QWriteLocker::QWriteLocker(QReadWriteLock *lock)-
743-
744 Constructs a QWriteLocker and locks \a lock for writing. The lock-
745 will be unlocked when the QWriteLocker is destroyed. If \c lock is-
746 zero, QWriteLocker does nothing.-
747-
748 \sa QReadWriteLock::lockForWrite()-
749*/-
750-
751/*!-
752 \fn QWriteLocker::~QWriteLocker()-
753-
754 Destroys the QWriteLocker and unlocks the lock that was passed to-
755 the constructor.-
756-
757 \sa QReadWriteLock::unlock()-
758*/-
759-
760/*!-
761 \fn void QWriteLocker::unlock()-
762-
763 Unlocks the lock associated with this locker.-
764-
765 \sa QReadWriteLock::unlock()-
766*/-
767-
768/*!-
769 \fn void QWriteLocker::relock()-
770-
771 Relocks an unlocked lock.-
772-
773 \sa unlock()-
774*/-
775-
776/*!-
777 \fn QReadWriteLock *QWriteLocker::readWriteLock() const-
778-
779 Returns a pointer to the read-write lock that was passed-
780 to the constructor.-
781*/-
782-
783QT_END_NAMESPACE-
784-
785#endif // QT_NO_THREAD-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9