OpenCoverage

qsemaphore.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qsemaphore.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
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 The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qsemaphore.h"-
41-
42#ifndef QT_NO_THREAD-
43#include "qmutex.h"-
44#include "qwaitcondition.h"-
45#include "qelapsedtimer.h"-
46#include "qdatetime.h"-
47-
48QT_BEGIN_NAMESPACE-
49-
50/*!-
51 \class QSemaphore-
52 \inmodule QtCore-
53 \brief The QSemaphore class provides a general counting semaphore.-
54-
55 \threadsafe-
56-
57 \ingroup thread-
58-
59 A semaphore is a generalization of a mutex. While a mutex can-
60 only be locked once, it's possible to acquire a semaphore-
61 multiple times. Semaphores are typically used to protect a-
62 certain number of identical resources.-
63-
64 Semaphores support two fundamental operations, acquire() and-
65 release():-
66-
67 \list-
68 \li acquire(\e{n}) tries to acquire \e n resources. If there aren't-
69 that many resources available, the call will block until this-
70 is the case.-
71 \li release(\e{n}) releases \e n resources.-
72 \endlist-
73-
74 There's also a tryAcquire() function that returns immediately if-
75 it cannot acquire the resources, and an available() function that-
76 returns the number of available resources at any time.-
77-
78 Example:-
79-
80 \snippet code/src_corelib_thread_qsemaphore.cpp 0-
81-
82 A typical application of semaphores is for controlling access to-
83 a circular buffer shared by a producer thread and a consumer-
84 thread. The \l{Semaphores Example} shows how-
85 to use QSemaphore to solve that problem.-
86-
87 A non-computing example of a semaphore would be dining at a-
88 restaurant. A semaphore is initialized with the number of chairs-
89 in the restaurant. As people arrive, they want a seat. As seats-
90 are filled, available() is decremented. As people leave, the-
91 available() is incremented, allowing more people to enter. If a-
92 party of 10 people want to be seated, but there are only 9 seats,-
93 those 10 people will wait, but a party of 4 people would be-
94 seated (taking the available seats to 5, making the party of 10-
95 people wait longer).-
96-
97 \sa QMutex, QWaitCondition, QThread, {Semaphores Example}-
98*/-
99-
100class QSemaphorePrivate {-
101public:-
102 inline QSemaphorePrivate(int n) : avail(n) { }
executed 1373213 times by 333 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
1373213
103-
104 QMutex mutex;-
105 QWaitCondition cond;-
106-
107 int avail;-
108};-
109-
110/*!-
111 Creates a new semaphore and initializes the number of resources-
112 it guards to \a n (by default, 0).-
113-
114 \sa release(), available()-
115*/-
116QSemaphore::QSemaphore(int n)-
117{-
118 Q_ASSERT_X(n >= 0, "QSemaphore", "parameter 'n' must be non-negative");-
119 d = new QSemaphorePrivate(n);-
120}
executed 1373213 times by 333 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
1373213
121-
122/*!-
123 Destroys the semaphore.-
124-
125 \warning Destroying a semaphore that is in use may result in-
126 undefined behavior.-
127*/-
128QSemaphore::~QSemaphore()-
129{
executed 1373225 times by 342 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
delete d; }
executed 1373225 times by 342 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
1373225
130-
131/*!-
132 Tries to acquire \c n resources guarded by the semaphore. If \a n-
133 > available(), this call will block until enough resources are-
134 available.-
135-
136 \sa release(), available(), tryAcquire()-
137*/-
138void QSemaphore::acquire(int n)-
139{-
140 Q_ASSERT_X(n >= 0, "QSemaphore::acquire", "parameter 'n' must be non-negative");-
141 QMutexLocker locker(&d->mutex);-
142 while (n > d->avail)
n > d->availDescription
TRUEevaluated 553926 times by 200 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
FALSEevaluated 3425674 times by 333 tests
Evaluated by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
553926-3425674
143 d->cond.wait(locker.mutex());
executed 553926 times by 200 tests: d->cond.wait(locker.mutex());
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
553926
144 d->avail -= n;-
145}
executed 3425674 times by 333 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
3425674
146-
147/*!-
148 Releases \a n resources guarded by the semaphore.-
149-
150 This function can be used to "create" resources as well. For-
151 example:-
152-
153 \snippet code/src_corelib_thread_qsemaphore.cpp 1-
154-
155 \sa acquire(), available()-
156*/-
157void QSemaphore::release(int n)-
158{-
159 Q_ASSERT_X(n >= 0, "QSemaphore::release", "parameter 'n' must be non-negative");-
160 QMutexLocker locker(&d->mutex);-
161 d->avail += n;-
162 d->cond.wakeAll();-
163}
executed 5056536 times by 334 tests: end of block
Executed by:
  • tst_Gestures
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_QAbstractButton
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSpinBox
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QApplication
  • tst_QBackingStore
  • tst_QBoxLayout
  • tst_QButtonGroup
  • tst_QCalendarWidget
  • tst_QCheckBox
  • tst_QColorDialog
  • tst_QColumnView
  • tst_QComboBox
  • tst_QCommandLinkButton
  • tst_QDBusAbstractAdaptor
  • tst_QDBusAbstractInterface
  • tst_QDBusConnection
  • ...
5056536
164-
165/*!-
166 Returns the number of resources currently available to the-
167 semaphore. This number can never be negative.-
168-
169 \sa acquire(), release()-
170*/-
171int QSemaphore::available() const-
172{-
173 QMutexLocker locker(&d->mutex);-
174 return d->avail;
executed 82 times by 2 tests: return d->avail;
Executed by:
  • tst_QDBusThreading
  • tst_QSemaphore
82
175}-
176-
177/*!-
178 Tries to acquire \c n resources guarded by the semaphore and-
179 returns \c true on success. If available() < \a n, this call-
180 immediately returns \c false without acquiring any resources.-
181-
182 Example:-
183-
184 \snippet code/src_corelib_thread_qsemaphore.cpp 2-
185-
186 \sa acquire()-
187*/-
188bool QSemaphore::tryAcquire(int n)-
189{-
190 Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");-
191 QMutexLocker locker(&d->mutex);-
192 if (n > d->avail)
n > d->availDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_QSemaphore
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QSemaphore
4-8
193 return false;
executed 8 times by 1 test: return false;
Executed by:
  • tst_QSemaphore
8
194 d->avail -= n;-
195 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_QSemaphore
4
196}-
197-
198/*!-
199 Tries to acquire \c n resources guarded by the semaphore and-
200 returns \c true on success. If available() < \a n, this call will-
201 wait for at most \a timeout milliseconds for resources to become-
202 available.-
203-
204 Note: Passing a negative number as the \a timeout is equivalent to-
205 calling acquire(), i.e. this function will wait forever for-
206 resources to become available if \a timeout is negative.-
207-
208 Example:-
209-
210 \snippet code/src_corelib_thread_qsemaphore.cpp 3-
211-
212 \sa acquire()-
213*/-
214bool QSemaphore::tryAcquire(int n, int timeout)-
215{-
216 Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");-
217 QMutexLocker locker(&d->mutex);-
218 if (timeout < 0) {
timeout < 0Description
TRUEnever evaluated
FALSEevaluated 1630882 times by 4 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
0-1630882
219 while (n > d->avail)
n > d->availDescription
TRUEnever evaluated
FALSEnever evaluated
0
220 d->cond.wait(locker.mutex());
never executed: d->cond.wait(locker.mutex());
0
221 } else {
never executed: end of block
0
222 QElapsedTimer timer;-
223 timer.start();-
224 while (n > d->avail) {
n > d->availDescription
TRUEevaluated 194055 times by 4 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
FALSEevaluated 1630859 times by 3 tests
Evaluated by:
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
194055-1630859
225 const qint64 elapsed = timer.elapsed();-
226 if (timeout - elapsed <= 0
timeout - elapsed <= 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QSemaphore
FALSEevaluated 194054 times by 4 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
1-194054
227 || !d->cond.wait(locker.mutex(), timeout - elapsed))
!d->cond.wait(...out - elapsed)Description
TRUEevaluated 22 times by 3 tests
Evaluated by:
  • tst_QReadWriteLock
  • tst_QSemaphore
  • tst_QThreadPool
FALSEevaluated 194032 times by 3 tests
Evaluated by:
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
22-194032
228 return false;
executed 23 times by 3 tests: return false;
Executed by:
  • tst_QReadWriteLock
  • tst_QSemaphore
  • tst_QThreadPool
23
229 }
executed 194032 times by 3 tests: end of block
Executed by:
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
194032
230 }
executed 1630859 times by 3 tests: end of block
Executed by:
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
1630859
231 d->avail -= n;-
232 return true;
executed 1630859 times by 3 tests: return true;
Executed by:
  • tst_QSemaphore
  • tst_QSslSocket
  • tst_QThreadPool
1630859
233-
234-
235}-
236-
237QT_END_NAMESPACE-
238-
239#endif // QT_NO_THREAD-
Source codeSwitch to Preprocessed file

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