1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the QtCore module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "qsharedmemory.h"
|
---|
43 | #include "qsharedmemory_p.h"
|
---|
44 | #include "qsystemsemaphore.h"
|
---|
45 | #include <qdir.h>
|
---|
46 | #include <qcryptographichash.h>
|
---|
47 | #ifdef Q_OS_SYMBIAN
|
---|
48 | #include <e32const.h>
|
---|
49 | #endif
|
---|
50 | #include <qdebug.h>
|
---|
51 |
|
---|
52 | QT_BEGIN_NAMESPACE
|
---|
53 |
|
---|
54 | #if !(defined(QT_NO_SHAREDMEMORY) && defined(QT_NO_SYSTEMSEMAPHORE))
|
---|
55 | /*!
|
---|
56 | \internal
|
---|
57 |
|
---|
58 | Generate a string from the key which can be any unicode string into
|
---|
59 | the subset that the win/unix kernel allows.
|
---|
60 |
|
---|
61 | On Unix this will be a file name
|
---|
62 | On Symbian key will be truncated to 80 characters
|
---|
63 | */
|
---|
64 | QString
|
---|
65 | QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
|
---|
66 | const QString &prefix)
|
---|
67 | {
|
---|
68 | if (key.isEmpty())
|
---|
69 | return QString();
|
---|
70 |
|
---|
71 | QString result = prefix;
|
---|
72 |
|
---|
73 | QString part1 = key;
|
---|
74 | part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString());
|
---|
75 | result.append(part1);
|
---|
76 | #ifdef Q_OS_SYMBIAN
|
---|
77 | return result.left(KMaxKernelName);
|
---|
78 | #endif
|
---|
79 |
|
---|
80 | QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex();
|
---|
81 | result.append(QLatin1String(hex));
|
---|
82 | #ifdef Q_OS_WIN
|
---|
83 | return result;
|
---|
84 | #else
|
---|
85 | return QDir::tempPath() + QLatin1Char('/') + result;
|
---|
86 | #endif
|
---|
87 | }
|
---|
88 | #endif // QT_NO_SHAREDMEMORY && QT_NO_SHAREDMEMORY
|
---|
89 |
|
---|
90 | #ifndef QT_NO_SHAREDMEMORY
|
---|
91 |
|
---|
92 | /*!
|
---|
93 | \class QSharedMemory
|
---|
94 | \since 4.4
|
---|
95 |
|
---|
96 | \brief The QSharedMemory class provides access to a shared memory segment.
|
---|
97 |
|
---|
98 | QSharedMemory provides access to a shared memory segment by multiple
|
---|
99 | threads and processes. It also provides a way for a single thread or
|
---|
100 | process to lock the memory for exclusive access.
|
---|
101 |
|
---|
102 | When using this class, be aware of the following platform
|
---|
103 | differences:
|
---|
104 |
|
---|
105 | \list
|
---|
106 |
|
---|
107 | \o Windows: QSharedMemory does not "own" the shared memory segment.
|
---|
108 | When all threads or processes that have an instance of QSharedMemory
|
---|
109 | attached to a particular shared memory segment have either destroyed
|
---|
110 | their instance of QSharedMemory or exited, the Windows kernel
|
---|
111 | releases the shared memory segment automatically.
|
---|
112 |
|
---|
113 | \o Unix: QSharedMemory "owns" the shared memory segment. When the
|
---|
114 | last thread or process that has an instance of QSharedMemory
|
---|
115 | attached to a particular shared memory segment detaches from the
|
---|
116 | segment by destroying its instance of QSharedMemory, the Unix kernel
|
---|
117 | release the shared memory segment. But if that last thread or
|
---|
118 | process crashes without running the QSharedMemory destructor, the
|
---|
119 | shared memory segment survives the crash.
|
---|
120 |
|
---|
121 | \o HP-UX: Only one attach to a shared memory segment is allowed per
|
---|
122 | process. This means that QSharedMemory should not be used across
|
---|
123 | multiple threads in the same process in HP-UX.
|
---|
124 |
|
---|
125 | \o Symbian: QSharedMemory does not "own" the shared memory segment.
|
---|
126 | When all threads or processes that have an instance of QSharedMemory
|
---|
127 | attached to a particular shared memory segment have either destroyed
|
---|
128 | their instance of QSharedMemory or exited, the Symbian kernel
|
---|
129 | releases the shared memory segment automatically.
|
---|
130 | Also, access to a shared memory segment cannot be limited to read-only
|
---|
131 | in Symbian.
|
---|
132 |
|
---|
133 | \endlist
|
---|
134 |
|
---|
135 | Remember to lock the shared memory with lock() before reading from
|
---|
136 | or writing to the shared memory, and remember to release the lock
|
---|
137 | with unlock() after you are done.
|
---|
138 |
|
---|
139 | Unlike QtSharedMemory, QSharedMemory automatically destroys the
|
---|
140 | shared memory segment when the last instance of QSharedMemory is
|
---|
141 | detached from the segment, and no references to the segment
|
---|
142 | remain. Do not mix using QtSharedMemory and QSharedMemory. Port
|
---|
143 | everything to QSharedMemory.
|
---|
144 |
|
---|
145 | \warning QSharedMemory changes the key in a Qt-specific way.
|
---|
146 | It is therefore currently not possible to use the shared memory of
|
---|
147 | non-Qt applications with QSharedMemory.
|
---|
148 | */
|
---|
149 |
|
---|
150 | /*!
|
---|
151 | \overload QSharedMemory()
|
---|
152 |
|
---|
153 | Constructs a shared memory object with the given \a parent. The
|
---|
154 | shared memory object's key is not set by the constructor, so the
|
---|
155 | shared memory object does not have an underlying shared memory
|
---|
156 | segment attached. The key must be set with setKey() before create()
|
---|
157 | or attach() can be used.
|
---|
158 |
|
---|
159 | \sa setKey()
|
---|
160 | */
|
---|
161 | QSharedMemory::QSharedMemory(QObject *parent)
|
---|
162 | : QObject(*new QSharedMemoryPrivate, parent)
|
---|
163 | {
|
---|
164 | }
|
---|
165 |
|
---|
166 | /*!
|
---|
167 | Constructs a shared memory object with the given \a parent and with
|
---|
168 | its key set to \a key. Because its key is set, its create() and
|
---|
169 | attach() functions can be called.
|
---|
170 |
|
---|
171 | \sa setKey(), create(), attach()
|
---|
172 | */
|
---|
173 | QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
|
---|
174 | : QObject(*new QSharedMemoryPrivate, parent)
|
---|
175 | {
|
---|
176 | setKey(key);
|
---|
177 | }
|
---|
178 |
|
---|
179 | /*!
|
---|
180 | The destructor clears the key, which forces the shared memory object
|
---|
181 | to \l {detach()} {detach} from its underlying shared memory
|
---|
182 | segment. If this shared memory object is the last one connected to
|
---|
183 | the shared memory segment, the detach() operation destroys the
|
---|
184 | shared memory segment.
|
---|
185 |
|
---|
186 | \sa detach() isAttached()
|
---|
187 | */
|
---|
188 | QSharedMemory::~QSharedMemory()
|
---|
189 | {
|
---|
190 | setKey(QString());
|
---|
191 | }
|
---|
192 |
|
---|
193 | /*!
|
---|
194 | Sets a new \a key for this shared memory object. If \a key and the
|
---|
195 | current key are the same, the function returns without doing
|
---|
196 | anything. If the shared memory object is attached to an underlying
|
---|
197 | shared memory segment, it will \l {detach()} {detach} from it before
|
---|
198 | setting the new key. This function does not do an attach().
|
---|
199 |
|
---|
200 | \sa key() isAttached()
|
---|
201 | */
|
---|
202 | void QSharedMemory::setKey(const QString &key)
|
---|
203 | {
|
---|
204 | Q_D(QSharedMemory);
|
---|
205 | if (key == d->key)
|
---|
206 | return;
|
---|
207 |
|
---|
208 | if (isAttached())
|
---|
209 | detach();
|
---|
210 | d->cleanHandle();
|
---|
211 | d->key = key;
|
---|
212 | }
|
---|
213 |
|
---|
214 | bool QSharedMemoryPrivate::initKey()
|
---|
215 | {
|
---|
216 | if (!cleanHandle())
|
---|
217 | return false;
|
---|
218 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
219 | systemSemaphore.setKey(QString(), 1);
|
---|
220 | systemSemaphore.setKey(key, 1);
|
---|
221 | if (systemSemaphore.error() != QSystemSemaphore::NoError) {
|
---|
222 | QString function = QLatin1String("QSharedMemoryPrivate::initKey");
|
---|
223 | errorString = QSharedMemory::tr("%1: unable to set key on lock").arg(function);
|
---|
224 | switch(systemSemaphore.error()) {
|
---|
225 | case QSystemSemaphore::PermissionDenied:
|
---|
226 | error = QSharedMemory::PermissionDenied;
|
---|
227 | break;
|
---|
228 | case QSystemSemaphore::KeyError:
|
---|
229 | error = QSharedMemory::KeyError;
|
---|
230 | break;
|
---|
231 | case QSystemSemaphore::AlreadyExists:
|
---|
232 | error = QSharedMemory::AlreadyExists;
|
---|
233 | break;
|
---|
234 | case QSystemSemaphore::NotFound:
|
---|
235 | error = QSharedMemory::NotFound;
|
---|
236 | break;
|
---|
237 | case QSystemSemaphore::OutOfResources:
|
---|
238 | error = QSharedMemory::OutOfResources;
|
---|
239 | break;
|
---|
240 | case QSystemSemaphore::UnknownError:
|
---|
241 | default:
|
---|
242 | error = QSharedMemory::UnknownError;
|
---|
243 | break;
|
---|
244 | }
|
---|
245 | return false;
|
---|
246 | }
|
---|
247 | #endif
|
---|
248 | errorString = QString();
|
---|
249 | error = QSharedMemory::NoError;
|
---|
250 | return true;
|
---|
251 | }
|
---|
252 |
|
---|
253 | /*!
|
---|
254 | Returns the key assigned to this shared memory. The key is the
|
---|
255 | identifier used by the operating system to identify the shared
|
---|
256 | memory segment. When QSharedMemory is used for interprocess
|
---|
257 | communication, the key is how each process attaches to the shared
|
---|
258 | memory segment through which the IPC occurs.
|
---|
259 |
|
---|
260 | \sa setKey()
|
---|
261 | */
|
---|
262 | QString QSharedMemory::key() const
|
---|
263 | {
|
---|
264 | Q_D(const QSharedMemory);
|
---|
265 | return d->key;
|
---|
266 | }
|
---|
267 |
|
---|
268 | /*!
|
---|
269 | Creates a shared memory segment of \a size bytes with the key passed
|
---|
270 | to the constructor or set with setKey(), attaches to the new shared
|
---|
271 | memory segment with the given access \a mode, and returns \tt true.
|
---|
272 | If a shared memory segment identified by the key already exists, the
|
---|
273 | attach operation is not performed, and \tt false is returned. When
|
---|
274 | the return value is \tt false, call error() to determine which error
|
---|
275 | occurred.
|
---|
276 |
|
---|
277 | \sa error()
|
---|
278 | */
|
---|
279 | bool QSharedMemory::create(int size, AccessMode mode)
|
---|
280 | {
|
---|
281 | Q_D(QSharedMemory);
|
---|
282 |
|
---|
283 | if (!d->initKey())
|
---|
284 | return false;
|
---|
285 |
|
---|
286 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
287 | #ifndef Q_OS_WIN
|
---|
288 | // Take ownership and force set initialValue because the semaphore
|
---|
289 | // might have already existed from a previous crash.
|
---|
290 | d->systemSemaphore.setKey(d->key, 1, QSystemSemaphore::Create);
|
---|
291 | #endif
|
---|
292 | #endif
|
---|
293 |
|
---|
294 | QString function = QLatin1String("QSharedMemory::create");
|
---|
295 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
296 | QSharedMemoryLocker lock(this);
|
---|
297 | if (!d->tryLocker(&lock, function))
|
---|
298 | return false;
|
---|
299 | #endif
|
---|
300 |
|
---|
301 | if (size <= 0) {
|
---|
302 | d->error = QSharedMemory::InvalidSize;
|
---|
303 | d->errorString =
|
---|
304 | QSharedMemory::tr("%1: create size is less then 0").arg(function);
|
---|
305 | return false;
|
---|
306 | }
|
---|
307 |
|
---|
308 | if (!d->create(size))
|
---|
309 | return false;
|
---|
310 |
|
---|
311 | return d->attach(mode);
|
---|
312 | }
|
---|
313 |
|
---|
314 | /*!
|
---|
315 | Returns the size of the attached shared memory segment. If no shared
|
---|
316 | memory segment is attached, 0 is returned.
|
---|
317 |
|
---|
318 | \sa create() attach()
|
---|
319 | */
|
---|
320 | int QSharedMemory::size() const
|
---|
321 | {
|
---|
322 | Q_D(const QSharedMemory);
|
---|
323 | return d->size;
|
---|
324 | }
|
---|
325 |
|
---|
326 | /*!
|
---|
327 | \enum QSharedMemory::AccessMode
|
---|
328 |
|
---|
329 | \value ReadOnly The shared memory segment is read-only. Writing to
|
---|
330 | the shared memory segment is not allowed. An attempt to write to a
|
---|
331 | shared memory segment created with ReadOnly causes the program to
|
---|
332 | abort.
|
---|
333 |
|
---|
334 | \value ReadWrite Reading and writing the shared memory segment are
|
---|
335 | both allowed.
|
---|
336 | */
|
---|
337 |
|
---|
338 | /*!
|
---|
339 | Attempts to attach the process to the shared memory segment
|
---|
340 | identified by the key that was passed to the constructor or to a
|
---|
341 | call to setKey(). The access \a mode is \l {QSharedMemory::}
|
---|
342 | {ReadWrite} by default. It can also be \l {QSharedMemory::}
|
---|
343 | {ReadOnly}. Returns true if the attach operation is successful. If
|
---|
344 | false is returned, call error() to determine which error occurred.
|
---|
345 | After attaching the shared memory segment, a pointer to the shared
|
---|
346 | memory can be obtained by calling data().
|
---|
347 |
|
---|
348 | \sa isAttached(), detach(), create()
|
---|
349 | */
|
---|
350 | bool QSharedMemory::attach(AccessMode mode)
|
---|
351 | {
|
---|
352 | Q_D(QSharedMemory);
|
---|
353 |
|
---|
354 | if (isAttached() || !d->initKey())
|
---|
355 | return false;
|
---|
356 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
357 | QSharedMemoryLocker lock(this);
|
---|
358 | if (!d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
|
---|
359 | return false;
|
---|
360 | #endif
|
---|
361 |
|
---|
362 | if (isAttached() || !d->handle())
|
---|
363 | return false;
|
---|
364 |
|
---|
365 | return d->attach(mode);
|
---|
366 | }
|
---|
367 |
|
---|
368 | /*!
|
---|
369 | Returns true if this process is attached to the shared memory
|
---|
370 | segment.
|
---|
371 |
|
---|
372 | \sa attach(), detach()
|
---|
373 | */
|
---|
374 | bool QSharedMemory::isAttached() const
|
---|
375 | {
|
---|
376 | Q_D(const QSharedMemory);
|
---|
377 | return (0 != d->memory);
|
---|
378 | }
|
---|
379 |
|
---|
380 | /*!
|
---|
381 | Detaches the process from the shared memory segment. If this was the
|
---|
382 | last process attached to the shared memory segment, then the shared
|
---|
383 | memory segment is released by the system, i.e., the contents are
|
---|
384 | destroyed. The function returns true if it detaches the shared
|
---|
385 | memory segment. If it returns false, it usually means the segment
|
---|
386 | either isn't attached, or it is locked by another process.
|
---|
387 |
|
---|
388 | \sa attach(), isAttached()
|
---|
389 | */
|
---|
390 | bool QSharedMemory::detach()
|
---|
391 | {
|
---|
392 | Q_D(QSharedMemory);
|
---|
393 | if (!isAttached())
|
---|
394 | return false;
|
---|
395 |
|
---|
396 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
397 | QSharedMemoryLocker lock(this);
|
---|
398 | if (!d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
|
---|
399 | return false;
|
---|
400 | #endif
|
---|
401 |
|
---|
402 | if (d->detach()) {
|
---|
403 | d->size = 0;
|
---|
404 | return true;
|
---|
405 | }
|
---|
406 | return false;
|
---|
407 | }
|
---|
408 |
|
---|
409 | /*!
|
---|
410 | Returns a pointer to the contents of the shared memory segment, if
|
---|
411 | one is attached. Otherwise it returns null. Remember to lock the
|
---|
412 | shared memory with lock() before reading from or writing to the
|
---|
413 | shared memory, and remember to release the lock with unlock() after
|
---|
414 | you are done.
|
---|
415 |
|
---|
416 | \sa attach()
|
---|
417 | */
|
---|
418 | void *QSharedMemory::data()
|
---|
419 | {
|
---|
420 | Q_D(QSharedMemory);
|
---|
421 | return d->memory;
|
---|
422 | }
|
---|
423 |
|
---|
424 | /*!
|
---|
425 | Returns a const pointer to the contents of the shared memory
|
---|
426 | segment, if one is attached. Otherwise it returns null. Remember to
|
---|
427 | lock the shared memory with lock() before reading from or writing to
|
---|
428 | the shared memory, and remember to release the lock with unlock()
|
---|
429 | after you are done.
|
---|
430 |
|
---|
431 | \sa attach() create()
|
---|
432 | */
|
---|
433 | const void* QSharedMemory::constData() const
|
---|
434 | {
|
---|
435 | Q_D(const QSharedMemory);
|
---|
436 | return d->memory;
|
---|
437 | }
|
---|
438 |
|
---|
439 | /*!
|
---|
440 | \overload data()
|
---|
441 | */
|
---|
442 | const void *QSharedMemory::data() const
|
---|
443 | {
|
---|
444 | Q_D(const QSharedMemory);
|
---|
445 | return d->memory;
|
---|
446 | }
|
---|
447 |
|
---|
448 | #ifndef QT_NO_SYSTEMSEMAPHORE
|
---|
449 | /*!
|
---|
450 | This is a semaphore that locks the shared memory segment for access
|
---|
451 | by this process and returns true. If another process has locked the
|
---|
452 | segment, this function blocks until the lock is released. Then it
|
---|
453 | acquires the lock and returns true. If this function returns false,
|
---|
454 | it means either that you have ignored a false return from create()
|
---|
455 | or attach(), or that QSystemSemaphore::acquire() failed due to an
|
---|
456 | unknown system error.
|
---|
457 |
|
---|
458 | \sa unlock(), data(), QSystemSemaphore::acquire()
|
---|
459 | */
|
---|
460 | bool QSharedMemory::lock()
|
---|
461 | {
|
---|
462 | Q_D(QSharedMemory);
|
---|
463 | if (d->lockedByMe) {
|
---|
464 | qWarning("QSharedMemory::lock: already locked");
|
---|
465 | return true;
|
---|
466 | }
|
---|
467 | if (d->systemSemaphore.acquire()) {
|
---|
468 | d->lockedByMe = true;
|
---|
469 | return true;
|
---|
470 | }
|
---|
471 | QString function = QLatin1String("QSharedMemory::lock");
|
---|
472 | d->errorString = QSharedMemory::tr("%1: unable to lock").arg(function);
|
---|
473 | d->error = QSharedMemory::LockError;
|
---|
474 | return false;
|
---|
475 | }
|
---|
476 |
|
---|
477 | /*!
|
---|
478 | Releases the lock on the shared memory segment and returns true, if
|
---|
479 | the lock is currently held by this process. If the segment is not
|
---|
480 | locked, or if the lock is held by another process, nothing happens
|
---|
481 | and false is returned.
|
---|
482 |
|
---|
483 | \sa lock()
|
---|
484 | */
|
---|
485 | bool QSharedMemory::unlock()
|
---|
486 | {
|
---|
487 | Q_D(QSharedMemory);
|
---|
488 | if (!d->lockedByMe)
|
---|
489 | return false;
|
---|
490 | d->lockedByMe = false;
|
---|
491 | if (d->systemSemaphore.release())
|
---|
492 | return true;
|
---|
493 | QString function = QLatin1String("QSharedMemory::unlock");
|
---|
494 | d->errorString = QSharedMemory::tr("%1: unable to unlock").arg(function);
|
---|
495 | d->error = QSharedMemory::LockError;
|
---|
496 | return false;
|
---|
497 | }
|
---|
498 | #endif // QT_NO_SYSTEMSEMAPHORE
|
---|
499 |
|
---|
500 | /*!
|
---|
501 | \enum QSharedMemory::SharedMemoryError
|
---|
502 |
|
---|
503 | \value NoError No error occurred.
|
---|
504 |
|
---|
505 | \value PermissionDenied The operation failed because the caller
|
---|
506 | didn't have the required permissions.
|
---|
507 |
|
---|
508 | \value InvalidSize A create operation failed because the requested
|
---|
509 | size was invalid.
|
---|
510 |
|
---|
511 | \value KeyError The operation failed because of an invalid key.
|
---|
512 |
|
---|
513 | \value AlreadyExists A create() operation failed because a shared
|
---|
514 | memory segment with the specified key already existed.
|
---|
515 |
|
---|
516 | \value NotFound An attach() failed because a shared memory segment
|
---|
517 | with the specified key could not be found.
|
---|
518 |
|
---|
519 | \value LockError The attempt to lock() the shared memory segment
|
---|
520 | failed because create() or attach() failed and returned false, or
|
---|
521 | because a system error occurred in QSystemSemaphore::acquire().
|
---|
522 |
|
---|
523 | \value OutOfResources A create() operation failed because there was
|
---|
524 | not enough memory available to fill the request.
|
---|
525 |
|
---|
526 | \value UnknownError Something else happened and it was bad.
|
---|
527 | */
|
---|
528 |
|
---|
529 | /*!
|
---|
530 | Returns a value indicating whether an error occurred, and, if so,
|
---|
531 | which error it was.
|
---|
532 |
|
---|
533 | \sa errorString()
|
---|
534 | */
|
---|
535 | QSharedMemory::SharedMemoryError QSharedMemory::error() const
|
---|
536 | {
|
---|
537 | Q_D(const QSharedMemory);
|
---|
538 | return d->error;
|
---|
539 | }
|
---|
540 |
|
---|
541 | /*!
|
---|
542 | Returns a text description of the last error that occurred. If
|
---|
543 | error() returns an \l {QSharedMemory::SharedMemoryError} {error
|
---|
544 | value}, call this function to get a text string that describes the
|
---|
545 | error.
|
---|
546 |
|
---|
547 | \sa error()
|
---|
548 | */
|
---|
549 | QString QSharedMemory::errorString() const
|
---|
550 | {
|
---|
551 | Q_D(const QSharedMemory);
|
---|
552 | return d->errorString;
|
---|
553 | }
|
---|
554 |
|
---|
555 | #endif // QT_NO_SHAREDMEMORY
|
---|
556 |
|
---|
557 | QT_END_NAMESPACE
|
---|