| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 |