thread/qreadwritelock.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
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 -
50#include "qreadwritelock_p.h" -
51 -
52QT_BEGIN_NAMESPACE -
53 -
54/*! \class QReadWriteLock -
55 \inmodule QtCore -
56 \brief The QReadWriteLock class provides read-write locking. -
57 -
58 \threadsafe -
59 -
60 \ingroup thread -
61 -
62 A read-write lock is a synchronization tool for protecting -
63 resources that can be accessed for reading and writing. This type -
64 of lock is useful if you want to allow multiple threads to have -
65 simultaneous read-only access, but as soon as one thread wants to -
66 write to the resource, all other threads must be blocked until -
67 the writing is complete. -
68 -
69 In many cases, QReadWriteLock is a direct competitor to QMutex. -
70 QReadWriteLock is a good choice if there are many concurrent -
71 reads and writing occurs infrequently. -
72 -
73 Example: -
74 -
75 \snippet code/src_corelib_thread_qreadwritelock.cpp 0 -
76 -
77 To ensure that writers aren't blocked forever by readers, readers -
78 attempting to obtain a lock will not succeed if there is a blocked -
79 writer waiting for access, even if the lock is currently only -
80 accessed by other readers. Also, if the lock is accessed by a -
81 writer and another writer comes in, that writer will have -
82 priority over any readers that might also be waiting. -
83 -
84 Like QMutex, a QReadWriteLock can be recursively locked by the -
85 same thread when constructed with \l{QReadWriteLock::Recursive} as -
86 \l{QReadWriteLock::RecursionMode}. In such cases, -
87 unlock() must be called the same number of times lockForWrite() or -
88 lockForRead() was called. Note that the lock type cannot be -
89 changed when trying to lock recursively, i.e. it is not possible -
90 to lock for reading in a thread that already has locked for -
91 writing (and vice versa). -
92 -
93 \sa QReadLocker, QWriteLocker, QMutex, QSemaphore -
94*/ -
95 -
96/*! -
97 \enum QReadWriteLock::RecursionMode -
98 \since 4.4 -
99 -
100 \value Recursive In this mode, a thread can lock the same -
101 QReadWriteLock multiple times and the mutex won't be unlocked -
102 until a corresponding number of unlock() calls have been made. -
103 -
104 \value NonRecursive In this mode, a thread may only lock a -
105 QReadWriteLock once. -
106 -
107 \sa QReadWriteLock() -
108*/ -
109 -
110/*! -
111 \since 4.4 -
112 -
113 Constructs a QReadWriteLock object in the given \a recursionMode. -
114 -
115 The default recursion mode is NonRecursive. -
116 -
117 \sa lockForRead(), lockForWrite(), RecursionMode -
118*/ -
119QReadWriteLock::QReadWriteLock(RecursionMode recursionMode) -
120 : d(new QReadWriteLockPrivate(recursionMode)) -
121{ }
executed: }
Execution Count:89833
89833
122 -
123/*! -
124 Destroys the QReadWriteLock object. -
125 -
126 \warning Destroying a read-write lock that is in use may result -
127 in undefined behavior. -
128*/ -
129QReadWriteLock::~QReadWriteLock() -
130{ -
131 delete d;
executed (the execution status of this line is deduced): delete d;
-
132}
executed: }
Execution Count:90794
90794
133 -
134/*! -
135 Locks the lock for reading. This function will block the current -
136 thread if another thread has locked for writing. -
137 -
138 It is not possible to lock for read if the thread already has -
139 locked for write. -
140 -
141 \sa unlock(), lockForWrite(), tryLockForRead() -
142*/ -
143void QReadWriteLock::lockForRead() -
144{ -
145 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
146 -
147 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
148 if (d->recursive) {
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:1813605
3-1813605
149 self = QThread::currentThreadId();
executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
150 -
151 QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
executed (the execution status of this line is deduced): QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
-
152 if (it != d->currentReaders.end()) {
partially evaluated: it != d->currentReaders.end()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:3
0-3
153 ++it.value();
never executed (the execution status of this line is deduced): ++it.value();
-
154 ++d->accessCount;
never executed (the execution status of this line is deduced): ++d->accessCount;
-
155 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()",
never executed (the execution status of this line is deduced): qt_noop();
-
156 "Overflow in lock counter"); -
157 return;
never executed: return;
0
158 } -
159 }
executed: }
Execution Count:3
3
160 -
161 while (d->accessCount < 0 || d->waitingWriters) {
evaluated: d->accessCount < 0
TRUEFALSE
yes
Evaluation Count:2793
yes
Evaluation Count:1820894
evaluated: d->waitingWriters
TRUEFALSE
yes
Evaluation Count:7286
yes
Evaluation Count:1813608
2793-1820894
162 ++d->waitingReaders;
executed (the execution status of this line is deduced): ++d->waitingReaders;
-
163 d->readerWait.wait(&d->mutex);
executed (the execution status of this line is deduced): d->readerWait.wait(&d->mutex);
-
164 --d->waitingReaders;
executed (the execution status of this line is deduced): --d->waitingReaders;
-
165 }
executed: }
Execution Count:10079
10079
166 if (d->recursive)
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:1813605
3-1813605
167 d->currentReaders.insert(self, 1);
executed: d->currentReaders.insert(self, 1);
Execution Count:3
3
168 -
169 ++d->accessCount;
executed (the execution status of this line is deduced): ++d->accessCount;
-
170 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter");
executed (the execution status of this line is deduced): qt_noop();
-
171}
executed: }
Execution Count:1813608
1813608
172 -
173/*! -
174 Attempts to lock for reading. If the lock was obtained, this -
175 function returns true, otherwise it returns false instead of -
176 waiting for the lock to become available, i.e. it does not block. -
177 -
178 The lock attempt will fail if another thread has locked for -
179 writing. -
180 -
181 If the lock was obtained, the lock must be unlocked with unlock() -
182 before another thread can successfully lock it for writing. -
183 -
184 It is not possible to lock for read if the thread already has -
185 locked for write. -
186 -
187 \sa unlock(), lockForRead() -
188*/ -
189bool QReadWriteLock::tryLockForRead() -
190{ -
191 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
192 -
193 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
194 if (d->recursive) {
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:36
yes
Evaluation Count:7
7-36
195 self = QThread::currentThreadId();
executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
196 -
197 QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
executed (the execution status of this line is deduced): QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
-
198 if (it != d->currentReaders.end()) {
evaluated: it != d->currentReaders.end()
TRUEFALSE
yes
Evaluation Count:11
yes
Evaluation Count:25
11-25
199 ++it.value();
executed (the execution status of this line is deduced): ++it.value();
-
200 ++d->accessCount;
executed (the execution status of this line is deduced): ++d->accessCount;
-
201 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
executed (the execution status of this line is deduced): qt_noop();
-
202 "Overflow in lock counter"); -
203 return true;
executed: return true;
Execution Count:11
11
204 } -
205 }
executed: }
Execution Count:25
25
206 -
207 if (d->accessCount < 0)
evaluated: d->accessCount < 0
TRUEFALSE
yes
Evaluation Count:23
yes
Evaluation Count:9
9-23
208 return false;
executed: return false;
Execution Count:23
23
209 if (d->recursive)
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:5
4-5
210 d->currentReaders.insert(self, 1);
executed: d->currentReaders.insert(self, 1);
Execution Count:4
4
211 -
212 ++d->accessCount;
executed (the execution status of this line is deduced): ++d->accessCount;
-
213 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
executed (the execution status of this line is deduced): qt_noop();
-
214 -
215 return true;
executed: return true;
Execution Count:9
9
216} -
217 -
218/*! \overload -
219 -
220 Attempts to lock for reading. This function returns true if the -
221 lock was obtained; otherwise it returns false. If another thread -
222 has locked for writing, this function will wait for at most \a -
223 timeout milliseconds for the lock to become available. -
224 -
225 Note: Passing a negative number as the \a timeout is equivalent to -
226 calling lockForRead(), i.e. this function will wait forever until -
227 lock can be locked for reading when \a timeout is negative. -
228 -
229 If the lock was obtained, the lock must be unlocked with unlock() -
230 before another thread can successfully lock it for writing. -
231 -
232 It is not possible to lock for read if the thread already has -
233 locked for write. -
234 -
235 \sa unlock(), lockForRead() -
236*/ -
237bool QReadWriteLock::tryLockForRead(int timeout) -
238{ -
239 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
240 -
241 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
242 if (d->recursive) {
partially evaluated: d->recursive
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:3
0-3
243 self = QThread::currentThreadId();
never executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
244 -
245 QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
never executed (the execution status of this line is deduced): QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
-
246 if (it != d->currentReaders.end()) {
never evaluated: it != d->currentReaders.end()
0
247 ++it.value();
never executed (the execution status of this line is deduced): ++it.value();
-
248 ++d->accessCount;
never executed (the execution status of this line is deduced): ++d->accessCount;
-
249 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
never executed (the execution status of this line is deduced): qt_noop();
-
250 "Overflow in lock counter"); -
251 return true;
never executed: return true;
0
252 } -
253 }
never executed: }
0
254 -
255 while (d->accessCount < 0 || d->waitingWriters) {
evaluated: d->accessCount < 0
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:2
partially evaluated: d->waitingWriters
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
256 ++d->waitingReaders;
executed (the execution status of this line is deduced): ++d->waitingReaders;
-
257 bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
executed (the execution status of this line is deduced): bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? (9223372036854775807L * 2UL + 1UL) : ulong(timeout));
-
258 --d->waitingReaders;
executed (the execution status of this line is deduced): --d->waitingReaders;
-
259 if (!success)
partially evaluated: !success
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
260 return false;
executed: return false;
Execution Count:1
1
261 }
never executed: }
0
262 if (d->recursive)
partially evaluated: d->recursive
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
263 d->currentReaders.insert(self, 1);
never executed: d->currentReaders.insert(self, 1);
0
264 -
265 ++d->accessCount;
executed (the execution status of this line is deduced): ++d->accessCount;
-
266 Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
executed (the execution status of this line is deduced): qt_noop();
-
267 -
268 return true;
executed: return true;
Execution Count:2
2
269} -
270 -
271/*! -
272 Locks the lock for writing. This function will block the current -
273 thread if another thread (including the current) has locked for -
274 reading or writing (unless the lock has been created using the -
275 \l{QReadWriteLock::Recursive} mode). -
276 -
277 It is not possible to lock for write if the thread already has -
278 locked for read. -
279 -
280 \sa unlock(), lockForRead(), tryLockForWrite() -
281*/ -
282void QReadWriteLock::lockForWrite() -
283{ -
284 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
285 -
286 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
287 if (d->recursive) {
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:1169355
4-1169355
288 self = QThread::currentThreadId();
executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
289 -
290 if (d->currentWriter == self) {
partially evaluated: d->currentWriter == self
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:4
0-4
291 --d->accessCount;
never executed (the execution status of this line is deduced): --d->accessCount;
-
292 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
never executed (the execution status of this line is deduced): qt_noop();
-
293 "Overflow in lock counter"); -
294 return;
never executed: return;
0
295 } -
296 }
executed: }
Execution Count:4
4
297 -
298 while (d->accessCount != 0) {
evaluated: d->accessCount != 0
TRUEFALSE
yes
Evaluation Count:152141
yes
Evaluation Count:1169359
152141-1169359
299 ++d->waitingWriters;
executed (the execution status of this line is deduced): ++d->waitingWriters;
-
300 d->writerWait.wait(&d->mutex);
executed (the execution status of this line is deduced): d->writerWait.wait(&d->mutex);
-
301 --d->waitingWriters;
executed (the execution status of this line is deduced): --d->waitingWriters;
-
302 }
executed: }
Execution Count:152141
152141
303 if (d->recursive)
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:1169355
4-1169355
304 d->currentWriter = self;
executed: d->currentWriter = self;
Execution Count:4
4
305 -
306 --d->accessCount;
executed (the execution status of this line is deduced): --d->accessCount;
-
307 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()", "Overflow in lock counter");
executed (the execution status of this line is deduced): qt_noop();
-
308}
executed: }
Execution Count:1169359
1169359
309 -
310/*! -
311 Attempts to lock for writing. If the lock was obtained, this -
312 function returns true; otherwise, it returns false immediately. -
313 -
314 The lock attempt will fail if another thread has locked for -
315 reading or writing. -
316 -
317 If the lock was obtained, the lock must be unlocked with unlock() -
318 before another thread can successfully lock it. -
319 -
320 It is not possible to lock for write if the thread already has -
321 locked for read. -
322 -
323 \sa unlock(), lockForWrite() -
324*/ -
325bool QReadWriteLock::tryLockForWrite() -
326{ -
327 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
328 -
329 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
330 if (d->recursive) {
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:39
yes
Evaluation Count:23
23-39
331 self = QThread::currentThreadId();
executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
332 -
333 if (d->currentWriter == self) {
evaluated: d->currentWriter == self
TRUEFALSE
yes
Evaluation Count:12
yes
Evaluation Count:27
12-27
334 --d->accessCount;
executed (the execution status of this line is deduced): --d->accessCount;
-
335 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
executed (the execution status of this line is deduced): qt_noop();
-
336 "Overflow in lock counter"); -
337 return true;
executed: return true;
Execution Count:12
12
338 } -
339 }
executed: }
Execution Count:27
27
340 -
341 if (d->accessCount != 0)
evaluated: d->accessCount != 0
TRUEFALSE
yes
Evaluation Count:32
yes
Evaluation Count:18
18-32
342 return false;
executed: return false;
Execution Count:32
32
343 if (d->recursive)
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:13
5-13
344 d->currentWriter = self;
executed: d->currentWriter = self;
Execution Count:5
5
345 -
346 --d->accessCount;
executed (the execution status of this line is deduced): --d->accessCount;
-
347 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
executed (the execution status of this line is deduced): qt_noop();
-
348 "Overflow in lock counter"); -
349 -
350 return true;
executed: return true;
Execution Count:18
18
351} -
352 -
353/*! \overload -
354 -
355 Attempts to lock for writing. This function returns true if the -
356 lock was obtained; otherwise it returns false. If another thread -
357 has locked for reading or writing, this function will wait for at -
358 most \a timeout milliseconds for the lock to become available. -
359 -
360 Note: Passing a negative number as the \a timeout is equivalent to -
361 calling lockForWrite(), i.e. this function will wait forever until -
362 lock can be locked for writing when \a timeout is negative. -
363 -
364 If the lock was obtained, the lock must be unlocked with unlock() -
365 before another thread can successfully lock it. -
366 -
367 It is not possible to lock for write if the thread already has -
368 locked for read. -
369 -
370 \sa unlock(), lockForWrite() -
371*/ -
372bool QReadWriteLock::tryLockForWrite(int timeout) -
373{ -
374 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
375 -
376 Qt::HANDLE self = 0;
executed (the execution status of this line is deduced): Qt::HANDLE self = 0;
-
377 if (d->recursive) {
partially evaluated: d->recursive
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
378 self = QThread::currentThreadId();
never executed (the execution status of this line is deduced): self = QThread::currentThreadId();
-
379 -
380 if (d->currentWriter == self) {
never evaluated: d->currentWriter == self
0
381 --d->accessCount;
never executed (the execution status of this line is deduced): --d->accessCount;
-
382 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
never executed (the execution status of this line is deduced): qt_noop();
-
383 "Overflow in lock counter"); -
384 return true;
never executed: return true;
0
385 } -
386 }
never executed: }
0
387 -
388 while (d->accessCount != 0) {
evaluated: d->accessCount != 0
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
389 ++d->waitingWriters;
executed (the execution status of this line is deduced): ++d->waitingWriters;
-
390 bool success = d->writerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
executed (the execution status of this line is deduced): bool success = d->writerWait.wait(&d->mutex, timeout < 0 ? (9223372036854775807L * 2UL + 1UL) : ulong(timeout));
-
391 --d->waitingWriters;
executed (the execution status of this line is deduced): --d->waitingWriters;
-
392 -
393 if (!success)
partially evaluated: !success
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
394 return false;
executed: return false;
Execution Count:1
1
395 }
never executed: }
0
396 if (d->recursive)
partially evaluated: d->recursive
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
0-1
397 d->currentWriter = self;
never executed: d->currentWriter = self;
0
398 -
399 --d->accessCount;
executed (the execution status of this line is deduced): --d->accessCount;
-
400 Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
executed (the execution status of this line is deduced): qt_noop();
-
401 "Overflow in lock counter"); -
402 -
403 return true;
executed: return true;
Execution Count:1
1
404} -
405 -
406/*! -
407 Unlocks the lock. -
408 -
409 Attempting to unlock a lock that is not locked is an error, and will result -
410 in program termination. -
411 -
412 \sa lockForRead(), lockForWrite(), tryLockForRead(), tryLockForWrite() -
413*/ -
414void QReadWriteLock::unlock() -
415{ -
416 QMutexLocker lock(&d->mutex);
executed (the execution status of this line is deduced): QMutexLocker lock(&d->mutex);
-
417 -
418 Q_ASSERT_X(d->accessCount != 0, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock");
executed (the execution status of this line is deduced): qt_noop();
-
419 -
420 bool unlocked = false;
executed (the execution status of this line is deduced): bool unlocked = false;
-
421 if (d->accessCount > 0) {
evaluated: d->accessCount > 0
TRUEFALSE
yes
Evaluation Count:1813630
yes
Evaluation Count:1169390
1169390-1813630
422 // releasing a read lock -
423 if (d->recursive) {
evaluated: d->recursive
TRUEFALSE
yes
Evaluation Count:18
yes
Evaluation Count:1813612
18-1813612
424 Qt::HANDLE self = QThread::currentThreadId();
executed (the execution status of this line is deduced): Qt::HANDLE self = QThread::currentThreadId();
-
425 QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
executed (the execution status of this line is deduced): QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
-
426 if (it != d->currentReaders.end()) {
partially evaluated: it != d->currentReaders.end()
TRUEFALSE
yes
Evaluation Count:18
no
Evaluation Count:0
0-18
427 if (--it.value() <= 0)
evaluated: --it.value() <= 0
TRUEFALSE
yes
Evaluation Count:7
yes
Evaluation Count:11
7-11
428 d->currentReaders.erase(it);
executed: d->currentReaders.erase(it);
Execution Count:7
7
429 }
executed: }
Execution Count:18
18
430 }
executed: }
Execution Count:18
18
431 -
432 unlocked = --d->accessCount == 0;
executed (the execution status of this line is deduced): unlocked = --d->accessCount == 0;
-
433 } else if (d->accessCount < 0 && ++d->accessCount == 0) {
executed: }
Execution Count:1813630
partially evaluated: d->accessCount < 0
TRUEFALSE
yes
Evaluation Count:1169390
no
Evaluation Count:0
evaluated: ++d->accessCount == 0
TRUEFALSE
yes
Evaluation Count:1169378
yes
Evaluation Count:12
0-1813630
434 // released a write lock -
435 unlocked = true;
executed (the execution status of this line is deduced): unlocked = true;
-
436 d->currentWriter = 0;
executed (the execution status of this line is deduced): d->currentWriter = 0;
-
437 }
executed: }
Execution Count:1169378
1169378
438 -
439 if (unlocked) {
evaluated: unlocked
TRUEFALSE
yes
Evaluation Count:2805032
yes
Evaluation Count:177987
177987-2805032
440 if (d->waitingWriters) {
evaluated: d->waitingWriters
TRUEFALSE
yes
Evaluation Count:152442
yes
Evaluation Count:2652591
152442-2652591
441 d->writerWait.wakeOne();
executed (the execution status of this line is deduced): d->writerWait.wakeOne();
-
442 } else if (d->waitingReaders) {
executed: }
Execution Count:152442
evaluated: d->waitingReaders
TRUEFALSE
yes
Evaluation Count:32113
yes
Evaluation Count:2620478
32113-2620478
443 d->readerWait.wakeAll();
executed (the execution status of this line is deduced): d->readerWait.wakeAll();
-
444 }
executed: }
Execution Count:32113
32113
445 } -
446}
executed: }
Execution Count:2983020
2983020
447 -
448/*! -
449 \class QReadLocker -
450 \inmodule QtCore -
451 \brief The QReadLocker class is a convenience class that -
452 simplifies locking and unlocking read-write locks for read access. -
453 -
454 \threadsafe -
455 -
456 \ingroup thread -
457 -
458 The purpose of QReadLocker (and QWriteLocker) is to simplify -
459 QReadWriteLock locking and unlocking. Locking and unlocking -
460 statements or in exception handling code is error-prone and -
461 difficult to debug. QReadLocker can be used in such situations -
462 to ensure that the state of the lock is always well-defined. -
463 -
464 Here's an example that uses QReadLocker to lock and unlock a -
465 read-write lock for reading: -
466 -
467 \snippet code/src_corelib_thread_qreadwritelock.cpp 1 -
468 -
469 It is equivalent to the following code: -
470 -
471 \snippet code/src_corelib_thread_qreadwritelock.cpp 2 -
472 -
473 The QMutexLocker documentation shows examples where the use of a -
474 locker object greatly simplifies programming. -
475 -
476 \sa QWriteLocker, QReadWriteLock -
477*/ -
478 -
479/*! -
480 \fn QReadLocker::QReadLocker(QReadWriteLock *lock) -
481 -
482 Constructs a QReadLocker and locks \a lock for reading. The lock -
483 will be unlocked when the QReadLocker is destroyed. If \c lock is -
484 zero, QReadLocker does nothing. -
485 -
486 \sa QReadWriteLock::lockForRead() -
487*/ -
488 -
489/*! -
490 \fn QReadLocker::~QReadLocker() -
491 -
492 Destroys the QReadLocker and unlocks the lock that was passed to -
493 the constructor. -
494 -
495 \sa QReadWriteLock::unlock() -
496*/ -
497 -
498/*! -
499 \fn void QReadLocker::unlock() -
500 -
501 Unlocks the lock associated with this locker. -
502 -
503 \sa QReadWriteLock::unlock() -
504*/ -
505 -
506/*! -
507 \fn void QReadLocker::relock() -
508 -
509 Relocks an unlocked lock. -
510 -
511 \sa unlock() -
512*/ -
513 -
514/*! -
515 \fn QReadWriteLock *QReadLocker::readWriteLock() const -
516 -
517 Returns a pointer to the read-write lock that was passed -
518 to the constructor. -
519*/ -
520 -
521/*! -
522 \class QWriteLocker -
523 \inmodule QtCore -
524 \brief The QWriteLocker class is a convenience class that -
525 simplifies locking and unlocking read-write locks for write access. -
526 -
527 \threadsafe -
528 -
529 \ingroup thread -
530 -
531 The purpose of QWriteLocker (and QReadLocker) is to simplify -
532 QReadWriteLock locking and unlocking. Locking and unlocking -
533 statements or in exception handling code is error-prone and -
534 difficult to debug. QWriteLocker can be used in such situations -
535 to ensure that the state of the lock is always well-defined. -
536 -
537 Here's an example that uses QWriteLocker to lock and unlock a -
538 read-write lock for writing: -
539 -
540 \snippet code/src_corelib_thread_qreadwritelock.cpp 3 -
541 -
542 It is equivalent to the following code: -
543 -
544 \snippet code/src_corelib_thread_qreadwritelock.cpp 4 -
545 -
546 The QMutexLocker documentation shows examples where the use of a -
547 locker object greatly simplifies programming. -
548 -
549 \sa QReadLocker, QReadWriteLock -
550*/ -
551 -
552/*! -
553 \fn QWriteLocker::QWriteLocker(QReadWriteLock *lock) -
554 -
555 Constructs a QWriteLocker and locks \a lock for writing. The lock -
556 will be unlocked when the QWriteLocker is destroyed. If \c lock is -
557 zero, QWriteLocker does nothing. -
558 -
559 \sa QReadWriteLock::lockForWrite() -
560*/ -
561 -
562/*! -
563 \fn QWriteLocker::~QWriteLocker() -
564 -
565 Destroys the QWriteLocker and unlocks the lock that was passed to -
566 the constructor. -
567 -
568 \sa QReadWriteLock::unlock() -
569*/ -
570 -
571/*! -
572 \fn void QWriteLocker::unlock() -
573 -
574 Unlocks the lock associated with this locker. -
575 -
576 \sa QReadWriteLock::unlock() -
577*/ -
578 -
579/*! -
580 \fn void QWriteLocker::relock() -
581 -
582 Relocks an unlocked lock. -
583 -
584 \sa unlock() -
585*/ -
586 -
587/*! -
588 \fn QReadWriteLock *QWriteLocker::readWriteLock() const -
589 -
590 Returns a pointer to the read-write lock that was passed -
591 to the constructor. -
592*/ -
593 -
594QT_END_NAMESPACE -
595 -
596#endif // QT_NO_THREAD -
597 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial