Qt 4.8
qsharedmemory.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
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 
53 
54 #if !(defined(QT_NO_SHAREDMEMORY) && defined(QT_NO_SYSTEMSEMAPHORE))
55 
67 QString
69  const QString &prefix)
70 {
71  if (key.isEmpty())
72  return QString();
73 
74  QString result = prefix;
75 
76  QString part1 = key;
77  part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString());
78  result.append(part1);
79 
81  result.append(QLatin1String(hex));
82 #ifdef Q_OS_WIN
83  return result;
84 #elif defined(Q_OS_SYMBIAN)
85  return result.left(KMaxKernelName);
86 #elif defined(QT_POSIX_IPC)
87  return QLatin1Char('/') + result;
88 #else
89  return QDir::tempPath() + QLatin1Char('/') + result;
90 #endif
91 }
92 #endif // QT_NO_SHAREDMEMORY && QT_NO_SHAREDMEMORY
93 
94 #ifndef QT_NO_SHAREDMEMORY
95 
178  : QObject(*new QSharedMemoryPrivate, parent)
179 {
180 }
181 
190  : QObject(*new QSharedMemoryPrivate, parent)
191 {
192  setKey(key);
193 }
194 
205 {
206  setKey(QString());
207 }
208 
224 {
226  if (key == d->key && d->makePlatformSafeKey(key) == d->nativeKey)
227  return;
228 
229  if (isAttached())
230  detach();
231  d->cleanHandle();
232  d->key = key;
233  d->nativeKey = d->makePlatformSafeKey(key);
234 }
235 
259 {
261  if (key == d->nativeKey && d->key.isNull())
262  return;
263 
264  if (isAttached())
265  detach();
266  d->cleanHandle();
267  d->key.clear();
268  d->nativeKey = key;
269 }
270 
272 {
273  cleanHandle();
274 
275 #ifndef QT_NO_SYSTEMSEMAPHORE
276  systemSemaphore.setKey(QString(), 1);
277  systemSemaphore.setKey(key, 1);
278  if (systemSemaphore.error() != QSystemSemaphore::NoError) {
279  QString function = QLatin1String("QSharedMemoryPrivate::initKey");
280  errorString = QSharedMemory::tr("%1: unable to set key on lock").arg(function);
281  switch(systemSemaphore.error()) {
284  break;
287  break;
290  break;
293  break;
296  break;
298  default:
300  break;
301  }
302  return false;
303  }
304 #endif
305  errorString.clear();
307  return true;
308 }
309 
322 {
323  Q_D(const QSharedMemory);
324  return d->key;
325 }
326 
343 {
344  Q_D(const QSharedMemory);
345  return d->nativeKey;
346 }
347 
359 {
361 
362  if (!d->initKey())
363  return false;
364 
365  if (size <= 0) {
366  d->error = QSharedMemory::InvalidSize;
367  d->errorString = QSharedMemory::tr("%1: create size is less then 0").arg(QLatin1String("QSharedMemory::create"));
368  return false;
369  }
370 
371 #ifndef QT_NO_SYSTEMSEMAPHORE
372 #ifndef Q_OS_WIN
373  // Take ownership and force set initialValue because the semaphore
374  // might have already existed from a previous crash.
375  d->systemSemaphore.setKey(d->key, 1, QSystemSemaphore::Create);
376 #endif
377 
379  if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::create")))
380  return false;
381 #endif
382 
383  if (!d->create(size))
384  return false;
385 
386  return d->attach(mode);
387 }
388 
396 {
397  Q_D(const QSharedMemory);
398  return d->size;
399 }
400 
426 {
428 
429  if (isAttached() || !d->initKey())
430  return false;
431 #ifndef QT_NO_SYSTEMSEMAPHORE
433  if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
434  return false;
435 #endif
436 
437  if (isAttached() || !d->handle())
438  return false;
439 
440  return d->attach(mode);
441 }
442 
450 {
451  Q_D(const QSharedMemory);
452  return (0 != d->memory);
453 }
454 
466 {
468  if (!isAttached())
469  return false;
470 
471 #ifndef QT_NO_SYSTEMSEMAPHORE
473  if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
474  return false;
475 #endif
476 
477  return d->detach();
478 }
479 
490 {
492  return d->memory;
493 }
494 
504 const void* QSharedMemory::constData() const
505 {
506  Q_D(const QSharedMemory);
507  return d->memory;
508 }
509 
513 const void *QSharedMemory::data() const
514 {
515  Q_D(const QSharedMemory);
516  return d->memory;
517 }
518 
519 #ifndef QT_NO_SYSTEMSEMAPHORE
520 
532 {
534  if (d->lockedByMe) {
535  qWarning("QSharedMemory::lock: already locked");
536  return true;
537  }
538  if (d->systemSemaphore.acquire()) {
539  d->lockedByMe = true;
540  return true;
541  }
542  QString function = QLatin1String("QSharedMemory::lock");
543  d->errorString = QSharedMemory::tr("%1: unable to lock").arg(function);
544  d->error = QSharedMemory::LockError;
545  return false;
546 }
547 
557 {
559  if (!d->lockedByMe)
560  return false;
561  d->lockedByMe = false;
562  if (d->systemSemaphore.release())
563  return true;
564  QString function = QLatin1String("QSharedMemory::unlock");
565  d->errorString = QSharedMemory::tr("%1: unable to unlock").arg(function);
566  d->error = QSharedMemory::LockError;
567  return false;
568 }
569 #endif // QT_NO_SYSTEMSEMAPHORE
570 
607 {
608  Q_D(const QSharedMemory);
609  return d->error;
610 }
611 
621 {
622  Q_D(const QSharedMemory);
623  return d->errorString;
624 }
625 
626 #endif // QT_NO_SHAREDMEMORY
627 
double d
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
bool unlock()
Releases the lock on the shared memory segment and returns true, if the lock is currently held by thi...
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
bool detach()
Detaches the process from the shared memory segment.
const void * constData() const
Returns a const pointer to the contents of the shared memory segment, if one is attached.
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
Q_CORE_EXPORT QTextStream & hex(QTextStream &s)
static char toHex(quint8 c)
Definition: qurl.cpp:4440
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool lock()
This is a semaphore that locks the shared memory segment for access by this process and returns true...
SharedMemoryError error() const
Returns a value indicating whether an error occurred, and, if so, which error it was.
Q_CORE_EXPORT void qWarning(const char *,...)
void setNativeKey(const QString &key)
Sets the native, platform specific, key for this shared memory object.
bool attach(AccessMode mode=ReadWrite)
Attempts to attach the process to the shared memory segment identified by the key that was passed to ...
static QString tempPath()
Returns the absolute path of the system&#39;s temporary directory.
Definition: qdir.cpp:1987
~QSharedMemory()
The destructor clears the key, which forces the shared memory object to detach() {detach} from its un...
bool isAttached() const
Returns true if this process is attached to the shared memory segment.
int size() const
Returns the size of the attached shared memory segment.
bool create(int size, AccessMode mode=ReadWrite)
Creates a shared memory segment of size bytes with the key passed to the constructor, set with setKey() or set with setNativeKey(), then attaches to the new shared memory segment with the given access mode and returns true.
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
QString & append(QChar c)
Definition: qstring.cpp:1777
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void * data()
Returns a pointer to the contents of the shared memory segment, if one is attached.
int key
The QSharedMemory class provides access to a shared memory segment.
Definition: qsharedmemory.h:57
QObject * parent
Definition: qobject.h:92
void setKey(const QString &key)
Sets the platform independent key for this shared memory object.
QString nativeKey() const
Returns the native, platform specific, key for this shared memory object.
QString errorString() const
Returns a text description of the last error that occurred.
QString key() const
Returns the key assigned with setKey() to this shared memory, or a null key if no key has been assign...
static QString makePlatformSafeKey(const QString &key, const QString &prefix=QLatin1String("qipc_sharedmemory_"))
Generate a string from the key which can be any unicode string into the subset that the win/unix kern...
QSharedMemory
Constructs a shared memory object with the given parent.
Helper class.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
static QByteArray hash(const QByteArray &data, Algorithm method)
Returns the hash of data using method.