Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/kernel/qsharedmemory.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 "qsharedmemory.h" | - | ||||||||||||
41 | #include "qsharedmemory_p.h" | - | ||||||||||||
42 | #include "qsystemsemaphore.h" | - | ||||||||||||
43 | #include <qdir.h> | - | ||||||||||||
44 | #include <qcryptographichash.h> | - | ||||||||||||
45 | #include <qdebug.h> | - | ||||||||||||
46 | #ifdef Q_OS_WIN | - | ||||||||||||
47 | # include <qt_windows.h> | - | ||||||||||||
48 | #endif | - | ||||||||||||
49 | - | |||||||||||||
50 | QT_BEGIN_NAMESPACE | - | ||||||||||||
51 | - | |||||||||||||
52 | #if !(defined(QT_NO_SHAREDMEMORY) && defined(QT_NO_SYSTEMSEMAPHORE)) | - | ||||||||||||
53 | /*! | - | ||||||||||||
54 | \internal | - | ||||||||||||
55 | - | |||||||||||||
56 | Generate a string from the key which can be any unicode string into | - | ||||||||||||
57 | the subset that the win/unix kernel allows. | - | ||||||||||||
58 | - | |||||||||||||
59 | On Unix this will be a file name | - | ||||||||||||
60 | */ | - | ||||||||||||
61 | QString | - | ||||||||||||
62 | QSharedMemoryPrivate::makePlatformSafeKey(const QString &key, | - | ||||||||||||
63 | const QString &prefix) | - | ||||||||||||
64 | { | - | ||||||||||||
65 | if (key.isEmpty())
| 3737-7354 | ||||||||||||
66 | return QString(); executed 3737 times by 2 tests: return QString(); Executed by:
| 3737 | ||||||||||||
67 | - | |||||||||||||
68 | QString result = prefix; | - | ||||||||||||
69 | - | |||||||||||||
70 | QString part1 = key; | - | ||||||||||||
71 | part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString()); | - | ||||||||||||
72 | result.append(part1); | - | ||||||||||||
73 | - | |||||||||||||
74 | QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex(); | - | ||||||||||||
75 | result.append(QLatin1String(hex)); | - | ||||||||||||
76 | #ifdef Q_OS_WIN | - | ||||||||||||
77 | return result; | - | ||||||||||||
78 | #elif defined(QT_POSIX_IPC) | - | ||||||||||||
79 | return QLatin1Char('/') + result; | - | ||||||||||||
80 | #else | - | ||||||||||||
81 | return QDir::tempPath() + QLatin1Char('/') + result; executed 7354 times by 4 tests: return QDir::tempPath() + QLatin1Char('/') + result; Executed by:
| 7354 | ||||||||||||
82 | #endif | - | ||||||||||||
83 | } | - | ||||||||||||
84 | #endif // QT_NO_SHAREDMEMORY && QT_NO_SHAREDMEMORY | - | ||||||||||||
85 | - | |||||||||||||
86 | #ifndef QT_NO_SHAREDMEMORY | - | ||||||||||||
87 | - | |||||||||||||
88 | /*! | - | ||||||||||||
89 | \class QSharedMemory | - | ||||||||||||
90 | \inmodule QtCore | - | ||||||||||||
91 | \since 4.4 | - | ||||||||||||
92 | - | |||||||||||||
93 | \brief The QSharedMemory class provides access to a shared memory segment. | - | ||||||||||||
94 | - | |||||||||||||
95 | QSharedMemory provides access to a shared memory segment by multiple | - | ||||||||||||
96 | threads and processes. It also provides a way for a single thread or | - | ||||||||||||
97 | process to lock the memory for exclusive access. | - | ||||||||||||
98 | - | |||||||||||||
99 | When using this class, be aware of the following platform | - | ||||||||||||
100 | differences: | - | ||||||||||||
101 | - | |||||||||||||
102 | \list | - | ||||||||||||
103 | - | |||||||||||||
104 | \li Windows: QSharedMemory does not "own" the shared memory segment. | - | ||||||||||||
105 | When all threads or processes that have an instance of QSharedMemory | - | ||||||||||||
106 | attached to a particular shared memory segment have either destroyed | - | ||||||||||||
107 | their instance of QSharedMemory or exited, the Windows kernel | - | ||||||||||||
108 | releases the shared memory segment automatically. | - | ||||||||||||
109 | - | |||||||||||||
110 | \li Unix: QSharedMemory "owns" the shared memory segment. When the | - | ||||||||||||
111 | last thread or process that has an instance of QSharedMemory | - | ||||||||||||
112 | attached to a particular shared memory segment detaches from the | - | ||||||||||||
113 | segment by destroying its instance of QSharedMemory, the Unix kernel | - | ||||||||||||
114 | release the shared memory segment. But if that last thread or | - | ||||||||||||
115 | process crashes without running the QSharedMemory destructor, the | - | ||||||||||||
116 | shared memory segment survives the crash. | - | ||||||||||||
117 | - | |||||||||||||
118 | \li HP-UX: Only one attach to a shared memory segment is allowed per | - | ||||||||||||
119 | process. This means that QSharedMemory should not be used across | - | ||||||||||||
120 | multiple threads in the same process in HP-UX. | - | ||||||||||||
121 | - | |||||||||||||
122 | \endlist | - | ||||||||||||
123 | - | |||||||||||||
124 | Remember to lock the shared memory with lock() before reading from | - | ||||||||||||
125 | or writing to the shared memory, and remember to release the lock | - | ||||||||||||
126 | with unlock() after you are done. | - | ||||||||||||
127 | - | |||||||||||||
128 | QSharedMemory automatically destroys the shared memory segment when | - | ||||||||||||
129 | the last instance of QSharedMemory is detached from the segment, and | - | ||||||||||||
130 | no references to the segment remain. | - | ||||||||||||
131 | - | |||||||||||||
132 | \warning QSharedMemory changes the key in a Qt-specific way, unless otherwise | - | ||||||||||||
133 | specified. Interoperation with non-Qt applications is achieved by first creating | - | ||||||||||||
134 | a default shared memory with QSharedMemory() and then setting a native key with | - | ||||||||||||
135 | setNativeKey(). When using native keys, shared memory is not protected against | - | ||||||||||||
136 | multiple accesses on it (for example, unable to lock()) and a user-defined mechanism | - | ||||||||||||
137 | should be used to achieve such protection. | - | ||||||||||||
138 | */ | - | ||||||||||||
139 | - | |||||||||||||
140 | /*! | - | ||||||||||||
141 | \overload QSharedMemory() | - | ||||||||||||
142 | - | |||||||||||||
143 | Constructs a shared memory object with the given \a parent. The | - | ||||||||||||
144 | shared memory object's key is not set by the constructor, so the | - | ||||||||||||
145 | shared memory object does not have an underlying shared memory | - | ||||||||||||
146 | segment attached. The key must be set with setKey() or setNativeKey() | - | ||||||||||||
147 | before create() or attach() can be used. | - | ||||||||||||
148 | - | |||||||||||||
149 | \sa setKey() | - | ||||||||||||
150 | */ | - | ||||||||||||
151 | QSharedMemory::QSharedMemory(QObject *parent) | - | ||||||||||||
152 | : QObject(*new QSharedMemoryPrivate, parent) | - | ||||||||||||
153 | { | - | ||||||||||||
154 | } executed 4 times by 3 tests: end of block Executed by:
| 4 | ||||||||||||
155 | - | |||||||||||||
156 | /*! | - | ||||||||||||
157 | Constructs a shared memory object with the given \a parent and with | - | ||||||||||||
158 | its key set to \a key. Because its key is set, its create() and | - | ||||||||||||
159 | attach() functions can be called. | - | ||||||||||||
160 | - | |||||||||||||
161 | \sa setKey(), create(), attach() | - | ||||||||||||
162 | */ | - | ||||||||||||
163 | QSharedMemory::QSharedMemory(const QString &key, QObject *parent) | - | ||||||||||||
164 | : QObject(*new QSharedMemoryPrivate, parent) | - | ||||||||||||
165 | { | - | ||||||||||||
166 | setKey(key); | - | ||||||||||||
167 | } executed 3608 times by 1 test: end of block Executed by:
| 3608 | ||||||||||||
168 | - | |||||||||||||
169 | /*! | - | ||||||||||||
170 | The destructor clears the key, which forces the shared memory object | - | ||||||||||||
171 | to \l {detach()} {detach} from its underlying shared memory | - | ||||||||||||
172 | segment. If this shared memory object is the last one connected to | - | ||||||||||||
173 | the shared memory segment, the detach() operation destroys the | - | ||||||||||||
174 | shared memory segment. | - | ||||||||||||
175 | - | |||||||||||||
176 | \sa detach(), isAttached() | - | ||||||||||||
177 | */ | - | ||||||||||||
178 | QSharedMemory::~QSharedMemory() | - | ||||||||||||
179 | { | - | ||||||||||||
180 | setKey(QString()); | - | ||||||||||||
181 | } executed 3611 times by 2 tests: end of block Executed by:
| 3611 | ||||||||||||
182 | - | |||||||||||||
183 | /*! | - | ||||||||||||
184 | Sets the platform independent \a key for this shared memory object. If \a key | - | ||||||||||||
185 | is the same as the current key, the function returns without doing anything. | - | ||||||||||||
186 | - | |||||||||||||
187 | You can call key() to retrieve the platform independent key. Internally, | - | ||||||||||||
188 | QSharedMemory converts this key into a platform specific key. If you instead | - | ||||||||||||
189 | call nativeKey(), you will get the platform specific, converted key. | - | ||||||||||||
190 | - | |||||||||||||
191 | If the shared memory object is attached to an underlying shared memory | - | ||||||||||||
192 | segment, it will \l {detach()} {detach} from it before setting the new key. | - | ||||||||||||
193 | This function does not do an attach(). | - | ||||||||||||
194 | - | |||||||||||||
195 | \sa key(), nativeKey(), isAttached() | - | ||||||||||||
196 | */ | - | ||||||||||||
197 | void QSharedMemory::setKey(const QString &key) | - | ||||||||||||
198 | { | - | ||||||||||||
199 | Q_D(QSharedMemory); | - | ||||||||||||
200 | if (key == d->key && d->makePlatformSafeKey(key) == d->nativeKey)
| 5-7101 | ||||||||||||
201 | return; executed 124 times by 2 tests: return; Executed by:
| 124 | ||||||||||||
202 | - | |||||||||||||
203 | if (isAttached())
| 3465-3641 | ||||||||||||
204 | detach(); executed 3465 times by 1 test: detach(); Executed by:
| 3465 | ||||||||||||
205 | d->cleanHandle(); | - | ||||||||||||
206 | d->key = key; | - | ||||||||||||
207 | d->nativeKey = d->makePlatformSafeKey(key); | - | ||||||||||||
208 | } executed 7106 times by 2 tests: end of block Executed by:
| 7106 | ||||||||||||
209 | - | |||||||||||||
210 | /*! | - | ||||||||||||
211 | \since 4.8 | - | ||||||||||||
212 | - | |||||||||||||
213 | Sets the native, platform specific, \a key for this shared memory object. If | - | ||||||||||||
214 | \a key is the same as the current native key, the function returns without | - | ||||||||||||
215 | doing anything. If all you want is to assign a key to a segment, you should | - | ||||||||||||
216 | call setKey() instead. | - | ||||||||||||
217 | - | |||||||||||||
218 | You can call nativeKey() to retrieve the native key. If a native key has been | - | ||||||||||||
219 | assigned, calling key() will return a null string. | - | ||||||||||||
220 | - | |||||||||||||
221 | If the shared memory object is attached to an underlying shared memory | - | ||||||||||||
222 | segment, it will \l {detach()} {detach} from it before setting the new key. | - | ||||||||||||
223 | This function does not do an attach(). | - | ||||||||||||
224 | - | |||||||||||||
225 | The application will not be portable if you set a native key. | - | ||||||||||||
226 | - | |||||||||||||
227 | \sa nativeKey(), key(), isAttached() | - | ||||||||||||
228 | */ | - | ||||||||||||
229 | void QSharedMemory::setNativeKey(const QString &key) | - | ||||||||||||
230 | { | - | ||||||||||||
231 | Q_D(QSharedMemory); | - | ||||||||||||
232 | if (key == d->nativeKey && d->key.isNull())
| 0-7 | ||||||||||||
233 | return; executed 2 times by 1 test: return; Executed by:
| 2 | ||||||||||||
234 | - | |||||||||||||
235 | if (isAttached())
| 0-7 | ||||||||||||
236 | detach(); never executed: detach(); | 0 | ||||||||||||
237 | d->cleanHandle(); | - | ||||||||||||
238 | d->key = QString(); | - | ||||||||||||
239 | d->nativeKey = key; | - | ||||||||||||
240 | } executed 7 times by 1 test: end of block Executed by:
| 7 | ||||||||||||
241 | - | |||||||||||||
242 | bool QSharedMemoryPrivate::initKey() | - | ||||||||||||
243 | { | - | ||||||||||||
244 | if (!cleanHandle())
| 0-3645 | ||||||||||||
245 | return false; never executed: return false; | 0 | ||||||||||||
246 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
247 | systemSemaphore.setKey(QString(), 1); | - | ||||||||||||
248 | systemSemaphore.setKey(key, 1); | - | ||||||||||||
249 | if (systemSemaphore.error() != QSystemSemaphore::NoError) {
| 54-3591 | ||||||||||||
250 | QString function = QLatin1String("QSharedMemoryPrivate::initKey"); | - | ||||||||||||
251 | errorString = QSharedMemory::tr("%1: unable to set key on lock").arg(function); | - | ||||||||||||
252 | switch(systemSemaphore.error()) { | - | ||||||||||||
253 | case QSystemSemaphore::PermissionDenied: never executed: case QSystemSemaphore::PermissionDenied: | 0 | ||||||||||||
254 | error = QSharedMemory::PermissionDenied; | - | ||||||||||||
255 | break; never executed: break; | 0 | ||||||||||||
256 | case QSystemSemaphore::KeyError: executed 52 times by 1 test: case QSystemSemaphore::KeyError: Executed by:
| 52 | ||||||||||||
257 | error = QSharedMemory::KeyError; | - | ||||||||||||
258 | break; executed 52 times by 1 test: break; Executed by:
| 52 | ||||||||||||
259 | case QSystemSemaphore::AlreadyExists: never executed: case QSystemSemaphore::AlreadyExists: | 0 | ||||||||||||
260 | error = QSharedMemory::AlreadyExists; | - | ||||||||||||
261 | break; never executed: break; | 0 | ||||||||||||
262 | case QSystemSemaphore::NotFound: never executed: case QSystemSemaphore::NotFound: | 0 | ||||||||||||
263 | error = QSharedMemory::NotFound; | - | ||||||||||||
264 | break; never executed: break; | 0 | ||||||||||||
265 | case QSystemSemaphore::OutOfResources: executed 2 times by 1 test: case QSystemSemaphore::OutOfResources: Executed by:
| 2 | ||||||||||||
266 | error = QSharedMemory::OutOfResources; | - | ||||||||||||
267 | break; executed 2 times by 1 test: break; Executed by:
| 2 | ||||||||||||
268 | case QSystemSemaphore::UnknownError: never executed: case QSystemSemaphore::UnknownError: | 0 | ||||||||||||
269 | default: never executed: default: | 0 | ||||||||||||
270 | error = QSharedMemory::UnknownError; | - | ||||||||||||
271 | break; never executed: break; | 0 | ||||||||||||
272 | } | - | ||||||||||||
273 | return false; executed 54 times by 1 test: return false; Executed by:
| 54 | ||||||||||||
274 | } | - | ||||||||||||
275 | #endif | - | ||||||||||||
276 | errorString = QString(); | - | ||||||||||||
277 | error = QSharedMemory::NoError; | - | ||||||||||||
278 | return true; executed 3591 times by 2 tests: return true; Executed by:
| 3591 | ||||||||||||
279 | } | - | ||||||||||||
280 | - | |||||||||||||
281 | /*! | - | ||||||||||||
282 | Returns the key assigned with setKey() to this shared memory, or a null key | - | ||||||||||||
283 | if no key has been assigned, or if the segment is using a nativeKey(). The | - | ||||||||||||
284 | key is the identifier used by Qt applications to identify the shared memory | - | ||||||||||||
285 | segment. | - | ||||||||||||
286 | - | |||||||||||||
287 | You can find the native, platform specific, key used by the operating system | - | ||||||||||||
288 | by calling nativeKey(). | - | ||||||||||||
289 | - | |||||||||||||
290 | \sa setKey(), setNativeKey() | - | ||||||||||||
291 | */ | - | ||||||||||||
292 | QString QSharedMemory::key() const | - | ||||||||||||
293 | { | - | ||||||||||||
294 | Q_D(const QSharedMemory); | - | ||||||||||||
295 | return d->key; executed 48 times by 1 test: return d->key; Executed by:
| 48 | ||||||||||||
296 | } | - | ||||||||||||
297 | - | |||||||||||||
298 | /*! | - | ||||||||||||
299 | \since 4.8 | - | ||||||||||||
300 | - | |||||||||||||
301 | Returns the native, platform specific, key for this shared memory object. The | - | ||||||||||||
302 | native key is the identifier used by the operating system to identify the | - | ||||||||||||
303 | shared memory segment. | - | ||||||||||||
304 | - | |||||||||||||
305 | You can use the native key to access shared memory segments that have not | - | ||||||||||||
306 | been created by Qt, or to grant shared memory access to non-Qt applications. | - | ||||||||||||
307 | - | |||||||||||||
308 | \sa setKey(), setNativeKey() | - | ||||||||||||
309 | */ | - | ||||||||||||
310 | QString QSharedMemory::nativeKey() const | - | ||||||||||||
311 | { | - | ||||||||||||
312 | Q_D(const QSharedMemory); | - | ||||||||||||
313 | return d->nativeKey; executed 39 times by 1 test: return d->nativeKey; Executed by:
| 39 | ||||||||||||
314 | } | - | ||||||||||||
315 | - | |||||||||||||
316 | /*! | - | ||||||||||||
317 | Creates a shared memory segment of \a size bytes with the key passed to the | - | ||||||||||||
318 | constructor, set with setKey() or set with setNativeKey(), then attaches to | - | ||||||||||||
319 | the new shared memory segment with the given access \a mode and returns | - | ||||||||||||
320 | \tt true. If a shared memory segment identified by the key already exists, | - | ||||||||||||
321 | the attach operation is not performed and \tt false is returned. When the | - | ||||||||||||
322 | return value is \tt false, call error() to determine which error occurred. | - | ||||||||||||
323 | - | |||||||||||||
324 | \sa error() | - | ||||||||||||
325 | */ | - | ||||||||||||
326 | bool QSharedMemory::create(int size, AccessMode mode) | - | ||||||||||||
327 | { | - | ||||||||||||
328 | Q_D(QSharedMemory); | - | ||||||||||||
329 | - | |||||||||||||
330 | if (!d->initKey())
| 1-3521 | ||||||||||||
331 | return false; executed 1 time by 1 test: return false; Executed by:
| 1 | ||||||||||||
332 | - | |||||||||||||
333 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
334 | #ifndef Q_OS_WIN | - | ||||||||||||
335 | // Take ownership and force set initialValue because the semaphore | - | ||||||||||||
336 | // might have already existed from a previous crash. | - | ||||||||||||
337 | d->systemSemaphore.setKey(d->key, 1, QSystemSemaphore::Create); | - | ||||||||||||
338 | #endif | - | ||||||||||||
339 | #endif | - | ||||||||||||
340 | - | |||||||||||||
341 | QString function = QLatin1String("QSharedMemory::create"); | - | ||||||||||||
342 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
343 | QSharedMemoryLocker lock(this); | - | ||||||||||||
344 | if (!d->key.isNull() && !d->tryLocker(&lock, function))
| 0-3468 | ||||||||||||
345 | return false; never executed: return false; | 0 | ||||||||||||
346 | #endif | - | ||||||||||||
347 | - | |||||||||||||
348 | if (size <= 0) {
| 1-3520 | ||||||||||||
349 | d->error = QSharedMemory::InvalidSize; | - | ||||||||||||
350 | d->errorString = | - | ||||||||||||
351 | QSharedMemory::tr("%1: create size is less then 0").arg(function); | - | ||||||||||||
352 | return false; executed 1 time by 1 test: return false; Executed by:
| 1 | ||||||||||||
353 | } | - | ||||||||||||
354 | - | |||||||||||||
355 | if (!d->create(size))
| 55-3465 | ||||||||||||
356 | return false; executed 55 times by 1 test: return false; Executed by:
| 55 | ||||||||||||
357 | - | |||||||||||||
358 | return d->attach(mode); executed 3465 times by 2 tests: return d->attach(mode); Executed by:
| 3465 | ||||||||||||
359 | } | - | ||||||||||||
360 | - | |||||||||||||
361 | /*! | - | ||||||||||||
362 | Returns the size of the attached shared memory segment. If no shared | - | ||||||||||||
363 | memory segment is attached, 0 is returned. | - | ||||||||||||
364 | - | |||||||||||||
365 | \sa create(), attach() | - | ||||||||||||
366 | */ | - | ||||||||||||
367 | int QSharedMemory::size() const | - | ||||||||||||
368 | { | - | ||||||||||||
369 | Q_D(const QSharedMemory); | - | ||||||||||||
370 | return d->size; executed 17 times by 1 test: return d->size; Executed by:
| 17 | ||||||||||||
371 | } | - | ||||||||||||
372 | - | |||||||||||||
373 | /*! | - | ||||||||||||
374 | \enum QSharedMemory::AccessMode | - | ||||||||||||
375 | - | |||||||||||||
376 | \value ReadOnly The shared memory segment is read-only. Writing to | - | ||||||||||||
377 | the shared memory segment is not allowed. An attempt to write to a | - | ||||||||||||
378 | shared memory segment created with ReadOnly causes the program to | - | ||||||||||||
379 | abort. | - | ||||||||||||
380 | - | |||||||||||||
381 | \value ReadWrite Reading and writing the shared memory segment are | - | ||||||||||||
382 | both allowed. | - | ||||||||||||
383 | */ | - | ||||||||||||
384 | - | |||||||||||||
385 | /*! | - | ||||||||||||
386 | Attempts to attach the process to the shared memory segment | - | ||||||||||||
387 | identified by the key that was passed to the constructor or to a | - | ||||||||||||
388 | call to setKey() or setNativeKey(). The access \a mode is \l {QSharedMemory::} | - | ||||||||||||
389 | {ReadWrite} by default. It can also be \l {QSharedMemory::} | - | ||||||||||||
390 | {ReadOnly}. Returns \c true if the attach operation is successful. If | - | ||||||||||||
391 | false is returned, call error() to determine which error occurred. | - | ||||||||||||
392 | After attaching the shared memory segment, a pointer to the shared | - | ||||||||||||
393 | memory can be obtained by calling data(). | - | ||||||||||||
394 | - | |||||||||||||
395 | \sa isAttached(), detach(), create() | - | ||||||||||||
396 | */ | - | ||||||||||||
397 | bool QSharedMemory::attach(AccessMode mode) | - | ||||||||||||
398 | { | - | ||||||||||||
399 | Q_D(QSharedMemory); | - | ||||||||||||
400 | - | |||||||||||||
401 | if (isAttached() || !d->initKey())
| 0-123 | ||||||||||||
402 | return false; executed 53 times by 1 test: return false; Executed by:
| 53 | ||||||||||||
403 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
404 | QSharedMemoryLocker lock(this); | - | ||||||||||||
405 | if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
| 0-69 | ||||||||||||
406 | return false; never executed: return false; | 0 | ||||||||||||
407 | #endif | - | ||||||||||||
408 | - | |||||||||||||
409 | if (isAttached() || !d->handle())
| 0-70 | ||||||||||||
410 | return false; executed 3 times by 1 test: return false; Executed by:
| 3 | ||||||||||||
411 | - | |||||||||||||
412 | return d->attach(mode); executed 67 times by 1 test: return d->attach(mode); Executed by:
| 67 | ||||||||||||
413 | } | - | ||||||||||||
414 | - | |||||||||||||
415 | /*! | - | ||||||||||||
416 | Returns \c true if this process is attached to the shared memory | - | ||||||||||||
417 | segment. | - | ||||||||||||
418 | - | |||||||||||||
419 | \sa attach(), detach() | - | ||||||||||||
420 | */ | - | ||||||||||||
421 | bool QSharedMemory::isAttached() const | - | ||||||||||||
422 | { | - | ||||||||||||
423 | Q_D(const QSharedMemory); | - | ||||||||||||
424 | return (0 != d->memory); executed 11064 times by 2 tests: return (0 != d->memory); Executed by:
| 11064 | ||||||||||||
425 | } | - | ||||||||||||
426 | - | |||||||||||||
427 | /*! | - | ||||||||||||
428 | Detaches the process from the shared memory segment. If this was the | - | ||||||||||||
429 | last process attached to the shared memory segment, then the shared | - | ||||||||||||
430 | memory segment is released by the system, i.e., the contents are | - | ||||||||||||
431 | destroyed. The function returns \c true if it detaches the shared | - | ||||||||||||
432 | memory segment. If it returns \c false, it usually means the segment | - | ||||||||||||
433 | either isn't attached, or it is locked by another process. | - | ||||||||||||
434 | - | |||||||||||||
435 | \sa attach(), isAttached() | - | ||||||||||||
436 | */ | - | ||||||||||||
437 | bool QSharedMemory::detach() | - | ||||||||||||
438 | { | - | ||||||||||||
439 | Q_D(QSharedMemory); | - | ||||||||||||
440 | if (!isAttached())
| 64-3531 | ||||||||||||
441 | return false; executed 64 times by 1 test: return false; Executed by:
| 64 | ||||||||||||
442 | - | |||||||||||||
443 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
444 | QSharedMemoryLocker lock(this); | - | ||||||||||||
445 | if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
| 0-3531 | ||||||||||||
446 | return false; never executed: return false; | 0 | ||||||||||||
447 | #endif | - | ||||||||||||
448 | - | |||||||||||||
449 | return d->detach(); executed 3531 times by 1 test: return d->detach(); Executed by:
| 3531 | ||||||||||||
450 | } | - | ||||||||||||
451 | - | |||||||||||||
452 | /*! | - | ||||||||||||
453 | Returns a pointer to the contents of the shared memory segment, if | - | ||||||||||||
454 | one is attached. Otherwise it returns null. Remember to lock the | - | ||||||||||||
455 | shared memory with lock() before reading from or writing to the | - | ||||||||||||
456 | shared memory, and remember to release the lock with unlock() after | - | ||||||||||||
457 | you are done. | - | ||||||||||||
458 | - | |||||||||||||
459 | \sa attach() | - | ||||||||||||
460 | */ | - | ||||||||||||
461 | void *QSharedMemory::data() | - | ||||||||||||
462 | { | - | ||||||||||||
463 | Q_D(QSharedMemory); | - | ||||||||||||
464 | return d->memory; executed 106 times by 2 tests: return d->memory; Executed by:
| 106 | ||||||||||||
465 | } | - | ||||||||||||
466 | - | |||||||||||||
467 | /*! | - | ||||||||||||
468 | Returns a const pointer to the contents of the shared memory | - | ||||||||||||
469 | segment, if one is attached. Otherwise it returns null. Remember to | - | ||||||||||||
470 | lock the shared memory with lock() before reading from or writing to | - | ||||||||||||
471 | the shared memory, and remember to release the lock with unlock() | - | ||||||||||||
472 | after you are done. | - | ||||||||||||
473 | - | |||||||||||||
474 | \sa attach(), create() | - | ||||||||||||
475 | */ | - | ||||||||||||
476 | const void* QSharedMemory::constData() const | - | ||||||||||||
477 | { | - | ||||||||||||
478 | Q_D(const QSharedMemory); | - | ||||||||||||
479 | return d->memory; never executed: return d->memory; | 0 | ||||||||||||
480 | } | - | ||||||||||||
481 | - | |||||||||||||
482 | /*! | - | ||||||||||||
483 | \overload data() | - | ||||||||||||
484 | */ | - | ||||||||||||
485 | const void *QSharedMemory::data() const | - | ||||||||||||
486 | { | - | ||||||||||||
487 | Q_D(const QSharedMemory); | - | ||||||||||||
488 | return d->memory; never executed: return d->memory; | 0 | ||||||||||||
489 | } | - | ||||||||||||
490 | - | |||||||||||||
491 | #ifndef QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
492 | /*! | - | ||||||||||||
493 | This is a semaphore that locks the shared memory segment for access | - | ||||||||||||
494 | by this process and returns \c true. If another process has locked the | - | ||||||||||||
495 | segment, this function blocks until the lock is released. Then it | - | ||||||||||||
496 | acquires the lock and returns \c true. If this function returns \c false, | - | ||||||||||||
497 | it means that you have ignored a false return from create() or attach(), | - | ||||||||||||
498 | that you have set the key with setNativeKey() or that | - | ||||||||||||
499 | QSystemSemaphore::acquire() failed due to an unknown system error. | - | ||||||||||||
500 | - | |||||||||||||
501 | \sa unlock(), data(), QSystemSemaphore::acquire() | - | ||||||||||||
502 | */ | - | ||||||||||||
503 | bool QSharedMemory::lock() | - | ||||||||||||
504 | { | - | ||||||||||||
505 | Q_D(QSharedMemory); | - | ||||||||||||
506 | if (d->lockedByMe) {
| 2-7581 | ||||||||||||
507 | qWarning("QSharedMemory::lock: already locked"); | - | ||||||||||||
508 | return true; executed 2 times by 1 test: return true; Executed by:
| 2 | ||||||||||||
509 | } | - | ||||||||||||
510 | if (d->systemSemaphore.acquire()) {
| 2-7579 | ||||||||||||
511 | d->lockedByMe = true; | - | ||||||||||||
512 | return true; executed 7579 times by 2 tests: return true; Executed by:
| 7579 | ||||||||||||
513 | } | - | ||||||||||||
514 | QString function = QLatin1String("QSharedMemory::lock"); | - | ||||||||||||
515 | d->errorString = QSharedMemory::tr("%1: unable to lock").arg(function); | - | ||||||||||||
516 | d->error = QSharedMemory::LockError; | - | ||||||||||||
517 | return false; executed 2 times by 1 test: return false; Executed by:
| 2 | ||||||||||||
518 | } | - | ||||||||||||
519 | - | |||||||||||||
520 | /*! | - | ||||||||||||
521 | Releases the lock on the shared memory segment and returns \c true, if | - | ||||||||||||
522 | the lock is currently held by this process. If the segment is not | - | ||||||||||||
523 | locked, or if the lock is held by another process, nothing happens | - | ||||||||||||
524 | and false is returned. | - | ||||||||||||
525 | - | |||||||||||||
526 | \sa lock() | - | ||||||||||||
527 | */ | - | ||||||||||||
528 | bool QSharedMemory::unlock() | - | ||||||||||||
529 | { | - | ||||||||||||
530 | Q_D(QSharedMemory); | - | ||||||||||||
531 | if (!d->lockedByMe)
| 54-7578 | ||||||||||||
532 | return false; executed 54 times by 1 test: return false; Executed by:
| 54 | ||||||||||||
533 | d->lockedByMe = false; | - | ||||||||||||
534 | if (d->systemSemaphore.release())
| 0-7578 | ||||||||||||
535 | return true; executed 7578 times by 2 tests: return true; Executed by:
| 7578 | ||||||||||||
536 | QString function = QLatin1String("QSharedMemory::unlock"); | - | ||||||||||||
537 | d->errorString = QSharedMemory::tr("%1: unable to unlock").arg(function); | - | ||||||||||||
538 | d->error = QSharedMemory::LockError; | - | ||||||||||||
539 | return false; never executed: return false; | 0 | ||||||||||||
540 | } | - | ||||||||||||
541 | #endif // QT_NO_SYSTEMSEMAPHORE | - | ||||||||||||
542 | - | |||||||||||||
543 | /*! | - | ||||||||||||
544 | \enum QSharedMemory::SharedMemoryError | - | ||||||||||||
545 | - | |||||||||||||
546 | \value NoError No error occurred. | - | ||||||||||||
547 | - | |||||||||||||
548 | \value PermissionDenied The operation failed because the caller | - | ||||||||||||
549 | didn't have the required permissions. | - | ||||||||||||
550 | - | |||||||||||||
551 | \value InvalidSize A create operation failed because the requested | - | ||||||||||||
552 | size was invalid. | - | ||||||||||||
553 | - | |||||||||||||
554 | \value KeyError The operation failed because of an invalid key. | - | ||||||||||||
555 | - | |||||||||||||
556 | \value AlreadyExists A create() operation failed because a shared | - | ||||||||||||
557 | memory segment with the specified key already existed. | - | ||||||||||||
558 | - | |||||||||||||
559 | \value NotFound An attach() failed because a shared memory segment | - | ||||||||||||
560 | with the specified key could not be found. | - | ||||||||||||
561 | - | |||||||||||||
562 | \value LockError The attempt to lock() the shared memory segment | - | ||||||||||||
563 | failed because create() or attach() failed and returned false, or | - | ||||||||||||
564 | because a system error occurred in QSystemSemaphore::acquire(). | - | ||||||||||||
565 | - | |||||||||||||
566 | \value OutOfResources A create() operation failed because there was | - | ||||||||||||
567 | not enough memory available to fill the request. | - | ||||||||||||
568 | - | |||||||||||||
569 | \value UnknownError Something else happened and it was bad. | - | ||||||||||||
570 | */ | - | ||||||||||||
571 | - | |||||||||||||
572 | /*! | - | ||||||||||||
573 | Returns a value indicating whether an error occurred, and, if so, | - | ||||||||||||
574 | which error it was. | - | ||||||||||||
575 | - | |||||||||||||
576 | \sa errorString() | - | ||||||||||||
577 | */ | - | ||||||||||||
578 | QSharedMemory::SharedMemoryError QSharedMemory::error() const | - | ||||||||||||
579 | { | - | ||||||||||||
580 | Q_D(const QSharedMemory); | - | ||||||||||||
581 | return d->error; executed 23 times by 1 test: return d->error; Executed by:
| 23 | ||||||||||||
582 | } | - | ||||||||||||
583 | - | |||||||||||||
584 | /*! | - | ||||||||||||
585 | Returns a text description of the last error that occurred. If | - | ||||||||||||
586 | error() returns an \l {QSharedMemory::SharedMemoryError} {error | - | ||||||||||||
587 | value}, call this function to get a text string that describes the | - | ||||||||||||
588 | error. | - | ||||||||||||
589 | - | |||||||||||||
590 | \sa error() | - | ||||||||||||
591 | */ | - | ||||||||||||
592 | QString QSharedMemory::errorString() const | - | ||||||||||||
593 | { | - | ||||||||||||
594 | Q_D(const QSharedMemory); | - | ||||||||||||
595 | return d->errorString; executed 18 times by 1 test: return d->errorString; Executed by:
| 18 | ||||||||||||
596 | } | - | ||||||||||||
597 | - | |||||||||||||
598 | #endif // QT_NO_SHAREDMEMORY | - | ||||||||||||
599 | - | |||||||||||||
600 | QT_END_NAMESPACE | - | ||||||||||||
Source code | Switch to Preprocessed file |