qsystemsemaphore.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/kernel/qsystemsemaphore.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtCore module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://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 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qsystemsemaphore.h"-
35#include "qsystemsemaphore_p.h"-
36#include <qglobal.h>-
37-
38QT_BEGIN_NAMESPACE-
39-
40#ifndef QT_NO_SYSTEMSEMAPHORE-
41-
42/*!-
43 \class QSystemSemaphore-
44 \inmodule QtCore-
45 \since 4.4-
46-
47 \brief The QSystemSemaphore class provides a general counting system semaphore.-
48-
49 A semaphore is a generalization of a mutex. While a mutex can be-
50 locked only once, a semaphore can be acquired multiple times.-
51 Typically, a semaphore is used to protect a certain number of-
52 identical resources.-
53-
54 Like its lighter counterpart QSemaphore, a QSystemSemaphore can be-
55 accessed from multiple \l {QThread} {threads}. Unlike QSemaphore, a-
56 QSystemSemaphore can also be accessed from multiple \l {QProcess}-
57 {processes}. This means QSystemSemaphore is a much heavier class, so-
58 if your application doesn't need to access your semaphores across-
59 multiple processes, you will probably want to use QSemaphore.-
60-
61 Semaphores support two fundamental operations, acquire() and release():-
62-
63 acquire() tries to acquire one resource. If there isn't a resource-
64 available, the call blocks until a resource becomes available. Then-
65 the resource is acquired and the call returns.-
66-
67 release() releases one resource so it can be acquired by another-
68 process. The function can also be called with a parameter n > 1,-
69 which releases n resources.-
70-
71 A system semaphore is created with a string key that other processes-
72 can use to use the same semaphore.-
73-
74 Example: Create a system semaphore-
75 \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 0-
76-
77 A typical application of system semaphores is for controlling access-
78 to a circular buffer shared by a producer process and a consumer-
79 processes.-
80-
81 \section1 Platform-Specific Behavior-
82-
83 When using this class, be aware of the following platform-
84 differences:-
85-
86 \b{Windows:} QSystemSemaphore does not own its underlying system-
87 semaphore. Windows owns it. This means that when all instances of-
88 QSystemSemaphore for a particular key have been destroyed, either by-
89 having their destructors called, or because one or more processes-
90 crash, Windows removes the underlying system semaphore.-
91-
92 \b{Unix:}-
93-
94 \list-
95 \li QSystemSemaphore owns the underlying system semaphore-
96 in Unix systems. This means that the last process having an instance of-
97 QSystemSemaphore for a particular key must remove the underlying-
98 system semaphore in its destructor. If the last process crashes-
99 without running the QSystemSemaphore destructor, Unix does not-
100 automatically remove the underlying system semaphore, and the-
101 semaphore survives the crash. A subsequent process that constructs a-
102 QSystemSemaphore with the same key will then be given the existing-
103 system semaphore. In that case, if the QSystemSemaphore constructor-
104 has specified its \l {QSystemSemaphore::AccessMode} {access mode} as-
105 \l {QSystemSemaphore::} {Open}, its initial resource count will not-
106 be reset to the one provided but remain set to the value it received-
107 in the crashed process. To protect against this, the first process-
108 to create a semaphore for a particular key (usually a server), must-
109 pass its \l {QSystemSemaphore::AccessMode} {access mode} as \l-
110 {QSystemSemaphore::} {Create}, which will force Unix to reset the-
111 resource count in the underlying system semaphore.-
112-
113 \li When a process using QSystemSemaphore terminates for-
114 any reason, Unix automatically reverses the effect of all acquire-
115 operations that were not released. Thus if the process acquires a-
116 resource and then exits without releasing it, Unix will release that-
117 resource.-
118-
119 \endlist-
120-
121 \sa QSharedMemory, QSemaphore-
122 */-
123-
124/*!-
125 Requests a system semaphore for the specified \a key. The parameters-
126 \a initialValue and \a mode are used according to the following-
127 rules, which are system dependent.-
128-
129 In Unix, if the \a mode is \l {QSystemSemaphore::} {Open} and the-
130 system already has a semaphore identified by \a key, that semaphore-
131 is used, and the semaphore's resource count is not changed, i.e., \a-
132 initialValue is ignored. But if the system does not already have a-
133 semaphore identified by \a key, it creates a new semaphore for that-
134 key and sets its resource count to \a initialValue.-
135-
136 In Unix, if the \a mode is \l {QSystemSemaphore::} {Create} and the-
137 system already has a semaphore identified by \a key, that semaphore-
138 is used, and its resource count is set to \a initialValue. If the-
139 system does not already have a semaphore identified by \a key, it-
140 creates a new semaphore for that key and sets its resource count to-
141 \a initialValue.-
142-
143 In Windows, \a mode is ignored, and the system always tries to-
144 create a semaphore for the specified \a key. If the system does not-
145 already have a semaphore identified as \a key, it creates the-
146 semaphore and sets its resource count to \a initialValue. But if the-
147 system already has a semaphore identified as \a key it uses that-
148 semaphore and ignores \a initialValue.-
149-
150 The \l {QSystemSemaphore::AccessMode} {mode} parameter is only used-
151 in Unix systems to handle the case where a semaphore survives a-
152 process crash. In that case, the next process to allocate a-
153 semaphore with the same \a key will get the semaphore that survived-
154 the crash, and unless \a mode is \l {QSystemSemaphore::} {Create},-
155 the resource count will not be reset to \a initialValue but will-
156 retain the initial value it had been given by the crashed process.-
157-
158 \sa acquire(), key()-
159 */-
160QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue, AccessMode mode)-
161 : d(new QSystemSemaphorePrivate)-
162{-
163 setKey(key, initialValue, mode);-
164}
executed 3735 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
3735
165-
166/*!-
167 The destructor destroys the QSystemSemaphore object, but the-
168 underlying system semaphore is not removed from the system unless-
169 this instance of QSystemSemaphore is the last one existing for that-
170 system semaphore.-
171-
172 Two important side effects of the destructor depend on the system.-
173 In Windows, if acquire() has been called for this semaphore but not-
174 release(), release() will not be called by the destructor, nor will-
175 the resource be released when the process exits normally. This would-
176 be a program bug which could be the cause of a deadlock in another-
177 process trying to acquire the same resource. In Unix, acquired-
178 resources that are not released before the destructor is called are-
179 automatically released when the process exits.-
180*/-
181QSystemSemaphore::~QSystemSemaphore()-
182{-
183 d->cleanHandle();-
184}
executed 3734 times by 4 tests: end of block
Executed by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qapplication - unknown status
  • tst_qsystemsemaphore - unknown status
3734
185-
186/*!-
187 \enum QSystemSemaphore::AccessMode-
188-
189 This enum is used by the constructor and setKey(). Its purpose is to-
190 enable handling the problem in Unix implementations of semaphores-
191 that survive a crash. In Unix, when a semaphore survives a crash, we-
192 need a way to force it to reset its resource count, when the system-
193 reuses the semaphore. In Windows, where semaphores can't survive a-
194 crash, this enum has no effect.-
195-
196 \value Open If the semaphore already exists, its initial resource-
197 count is not reset. If the semaphore does not already exist, it is-
198 created and its initial resource count set.-
199-
200 \value Create QSystemSemaphore takes ownership of the semaphore and-
201 sets its resource count to the requested value, regardless of-
202 whether the semaphore already exists by having survived a crash.-
203 This value should be passed to the constructor, when the first-
204 semaphore for a particular key is constructed and you know that if-
205 the semaphore already exists it could only be because of a crash. In-
206 Windows, where a semaphore can't survive a crash, Create and Open-
207 have the same behavior.-
208*/-
209-
210/*!-
211 This function works the same as the constructor. It reconstructs-
212 this QSystemSemaphore object. If the new \a key is different from-
213 the old key, calling this function is like calling the destructor of-
214 the semaphore with the old key, then calling the constructor to-
215 create a new semaphore with the new \a key. The \a initialValue and-
216 \a mode parameters are as defined for the constructor.-
217-
218 \sa QSystemSemaphore(), key()-
219 */-
220void QSystemSemaphore::setKey(const QString &key, int initialValue, AccessMode mode)-
221{-
222 if (key == d->key && mode == Open)
key == d->keyDescription
TRUEevaluated 10883 times by 4 tests
Evaluated by:
  • tst_QApplication
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
FALSEevaluated 3666 times by 4 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
mode == OpenDescription
TRUEevaluated 7362 times by 4 tests
Evaluated by:
  • tst_QApplication
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
FALSEevaluated 3521 times by 2 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
3521-10883
223 return;
executed 7362 times by 4 tests: return;
Executed by:
  • tst_QApplication
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
7362
224 d->clearError();-
225#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)-
226 // optimization to not destroy/create the file & semaphore-
227 if (key == d->key && mode == Create && d->createdSemaphore && d->createdFile) {
key == d->keyDescription
TRUEevaluated 3521 times by 2 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
FALSEevaluated 3666 times by 4 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
mode == CreateDescription
TRUEevaluated 3521 times by 2 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
FALSEnever evaluated
d->createdSemaphoreDescription
TRUEevaluated 3466 times by 2 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
FALSEevaluated 55 times by 1 test
Evaluated by:
  • tst_QSharedMemory
d->createdFileDescription
TRUEevaluated 3466 times by 2 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
FALSEnever evaluated
0-3666
228 d->initialValue = initialValue;-
229 d->unix_key = -1;-
230 d->handle(mode);-
231 return;
executed 3466 times by 2 tests: return;
Executed by:
  • tst_QSharedMemory
  • tst_qsharedmemory - unknown status
3466
232 }-
233#endif-
234 d->cleanHandle();-
235 d->key = key;-
236 d->initialValue = initialValue;-
237 // cache the file name so it doesn't have to be generated all the time.-
238 d->fileName = d->makeKeyFileName();-
239 d->handle(mode);-
240}
executed 3721 times by 4 tests: end of block
Executed by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
3721
241-
242/*!-
243 Returns the key assigned to this system semaphore. The key is the-
244 name by which the semaphore can be accessed from other processes.-
245-
246 \sa setKey()-
247 */-
248QString QSystemSemaphore::key() const-
249{-
250 return d->key;
executed 6 times by 1 test: return d->key;
Executed by:
  • tst_QSystemSemaphore
6
251}-
252-
253/*!-
254 Acquires one of the resources guarded by this semaphore, if there is-
255 one available, and returns \c true. If all the resources guarded by this-
256 semaphore have already been acquired, the call blocks until one of-
257 them is released by another process or thread having a semaphore-
258 with the same key.-
259-
260 If false is returned, a system error has occurred. Call error()-
261 to get a value of QSystemSemaphore::SystemSemaphoreError that-
262 indicates which error occurred.-
263-
264 \sa release()-
265 */-
266bool QSystemSemaphore::acquire()-
267{-
268 return d->modifySemaphore(-1);
executed 7661 times by 4 tests: return d->modifySemaphore(-1);
Executed by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
7661
269}-
270-
271/*!-
272 Releases \a n resources guarded by the semaphore. Returns \c true-
273 unless there is a system error.-
274-
275 Example: Create a system semaphore having five resources; acquire-
276 them all and then release them all.-
277-
278 \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 1-
279-
280 This function can also "create" resources. For example, immediately-
281 following the sequence of statements above, suppose we add the-
282 statement:-
283-
284 \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 2-
285-
286 Ten new resources are now guarded by the semaphore, in addition to-
287 the five that already existed. You would not normally use this-
288 function to create more resources.-
289-
290 \sa acquire()-
291 */-
292bool QSystemSemaphore::release(int n)-
293{-
294 if (n == 0)
n == 0Description
TRUEnever evaluated
FALSEevaluated 7659 times by 4 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
0-7659
295 return true;
never executed: return true;
0
296 if (n < 0) {
n < 0Description
TRUEnever evaluated
FALSEevaluated 7659 times by 4 tests
Evaluated by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
0-7659
297 qWarning("QSystemSemaphore::release: n is negative.");-
298 return false;
never executed: return false;
0
299 }-
300 return d->modifySemaphore(n);
executed 7659 times by 4 tests: return d->modifySemaphore(n);
Executed by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
  • tst_qsystemsemaphore - unknown status
7659
301}-
302-
303/*!-
304 Returns a value indicating whether an error occurred, and, if so,-
305 which error it was.-
306-
307 \sa errorString()-
308 */-
309QSystemSemaphore::SystemSemaphoreError QSystemSemaphore::error() const-
310{-
311 return d->error;
executed 3721 times by 3 tests: return d->error;
Executed by:
  • tst_QSharedMemory
  • tst_QSystemSemaphore
  • tst_qsharedmemory - unknown status
3721
312}-
313-
314/*!-
315 \enum QSystemSemaphore::SystemSemaphoreError-
316-
317 \value NoError No error occurred.-
318-
319 \value PermissionDenied The operation failed because the caller-
320 didn't have the required permissions.-
321-
322 \value KeyError The operation failed because of an invalid key.-
323-
324 \value AlreadyExists The operation failed because a system-
325 semaphore with the specified key already existed.-
326-
327 \value NotFound The operation failed because a system semaphore-
328 with the specified key could not be found.-
329-
330 \value OutOfResources The operation failed because there was-
331 not enough memory available to fill the request.-
332-
333 \value UnknownError Something else happened and it was bad.-
334*/-
335-
336/*!-
337 Returns a text description of the last error that occurred. If-
338 error() returns an \l {QSystemSemaphore::SystemSemaphoreError} {error-
339 value}, call this function to get a text string that describes the-
340 error.-
341-
342 \sa error()-
343 */-
344QString QSystemSemaphore::errorString() const-
345{-
346 return d->errorString;
executed 9 times by 1 test: return d->errorString;
Executed by:
  • tst_QSystemSemaphore
9
347}-
348-
349#endif // QT_NO_SYSTEMSEMAPHORE-
350-
351QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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