summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qwssharedmemory.cpp
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-06-23 11:11:39 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-06-23 11:11:39 (GMT)
commitd29adf474c694d77ef136a75717f10398f76f7fb (patch)
tree51cad9bfa91f074277409837e0739272b957eb0b /src/gui/embedded/qwssharedmemory.cpp
parentaae54f2fc238b7162336d71c61dfb01fd425b36f (diff)
parent2d930fdabccad6bfbbd0075610a302027c8d499b (diff)
downloadQt-d29adf474c694d77ef136a75717f10398f76f7fb.zip
Qt-d29adf474c694d77ef136a75717f10398f76f7fb.tar.gz
Qt-d29adf474c694d77ef136a75717f10398f76f7fb.tar.bz2
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-symbian-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-symbian-team: (33 commits) symbian socket engine: resolve some fixme and todo items trivial: fix typo in comment Fix QDeclarativeInspector when starting with ,block changelog docu update for QNX 6.5 get rid of anacronysm massive improvements for the QNX screen driver massive improvements for the QNX mouse driver massive improvements for the QNX keyboard driver disable the Embedded Linux data directory permissions check for QNX skip two subtests that are known to fail on QNX implement POSIX IPC based QLock, QWSLock and QWSSharedMemory backends implement POSIX IPC based QSystemSemaphore and QSharedMemory backends add a configure-time check for an IPC support make QProcess really work on QNX make the kernel attempt to emulate an instruction with a misaligned access use RoundRobin scheduler by default on QNX a major refactoring of the mkspecs tree for QNX buildfix for qmake qmlplugindump: Add -v option. ...
Diffstat (limited to 'src/gui/embedded/qwssharedmemory.cpp')
-rw-r--r--src/gui/embedded/qwssharedmemory.cpp89
1 files changed, 88 insertions, 1 deletions
diff --git a/src/gui/embedded/qwssharedmemory.cpp b/src/gui/embedded/qwssharedmemory.cpp
index a677626..853de61 100644
--- a/src/gui/embedded/qwssharedmemory.cpp
+++ b/src/gui/embedded/qwssharedmemory.cpp
@@ -45,14 +45,37 @@
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/shm.h>
+#else
+#include <sys/mman.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <private/qcore_unix_p.h>
//#define QT_SHM_DEBUG
QT_BEGIN_NAMESPACE
+#ifdef QT_POSIX_IPC
+#include <QtCore/QAtomicInt>
+
+static QBasicAtomicInt localUniqueId = Q_BASIC_ATOMIC_INITIALIZER(1);
+
+static inline QByteArray makeKey(int id)
+{
+ return "/qwsshm_" + QByteArray::number(id, 16);
+}
+#endif
+
QWSSharedMemory::QWSSharedMemory()
: shmId(-1), shmBase(0), shmSize(0)
+#ifdef QT_POSIX_IPC
+ , hand(-1)
+#endif
{
}
@@ -66,19 +89,47 @@ bool QWSSharedMemory::create(int size)
if (shmId != -1)
detach();
+#ifndef QT_POSIX_IPC
shmId = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600);
+#else
+ // ### generate really unique IDs
+ shmId = (getpid() << 16) + (localUniqueId.fetchAndAddRelaxed(1) % ushort(-1));
+ QByteArray shmName = makeKey(shmId);
+ EINTR_LOOP(hand, shm_open(shmName.constData(), O_RDWR | O_CREAT, 0660));
+ if (hand != -1) {
+ // the size may only be set once; ignore errors
+ int ret;
+ EINTR_LOOP(ret, ftruncate(hand, size));
+ if (ret == -1)
+ shmId = -1;
+ } else {
+ shmId = -1;
+ }
+#endif
if (shmId == -1) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::create():");
qWarning("Error allocating shared memory of size %d", size);
#endif
+ detach();
return false;
}
+
+#ifndef QT_POSIX_IPC
shmBase = shmat(shmId, 0, 0);
// On Linux, it is possible to attach a shared memory segment even if it
// is already marked to be deleted. However, POSIX.1-2001 does not specify
// this behaviour and many other implementations do not support it.
shmctl(shmId, IPC_RMID, 0);
+#else
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) != -1) {
+ shmSize = st.st_size;
+ // grab the memory
+ shmBase = mmap(0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, hand, 0);
+ }
+#endif
if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::create():");
@@ -102,7 +153,21 @@ bool QWSSharedMemory::attach(int id)
return false;
shmId = id;
+#ifndef QT_POSIX_IPC
shmBase = shmat(shmId, 0, 0);
+#else
+ QByteArray shmName = makeKey(shmId);
+ EINTR_LOOP(hand, shm_open(shmName.constData(), O_RDWR, 0660));
+ if (hand != -1) {
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) != -1) {
+ shmSize = st.st_size;
+ // grab the memory
+ shmBase = mmap(0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, hand, 0);
+ }
+ }
+#endif
if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::attach():");
@@ -117,8 +182,28 @@ bool QWSSharedMemory::attach(int id)
void QWSSharedMemory::detach()
{
+#ifndef QT_POSIX_IPC
if (shmBase && shmBase != (void*)-1)
shmdt(shmBase);
+#else
+ if (shmBase && shmBase != (void*)-1)
+ munmap(shmBase, shmSize);
+ if (hand > 0) {
+ // get the number of current attachments
+ int shm_nattch = 0;
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == 0) {
+ // subtract 2 from linkcount: one for our own open and one for the dir entry
+ shm_nattch = st.st_nlink - 2;
+ }
+ qt_safe_close(hand);
+ // if there are no attachments then unlink the shared memory
+ if (shm_nattch == 0) {
+ QByteArray shmName = makeKey(shmId);
+ shm_unlink(shmName.constData());
+ }
+ }
+#endif
shmBase = 0;
shmSize = 0;
shmId = -1;
@@ -129,11 +214,13 @@ int QWSSharedMemory::size() const
if (shmId == -1)
return 0;
+#ifndef QT_POSIX_IPC
if (!shmSize) {
struct shmid_ds shm;
shmctl(shmId, IPC_STAT, &shm);
- const_cast<QWSSharedMemory *>(this)->shmSize = shm.shm_segsz;
+ shmSize = shm.shm_segsz;
}
+#endif
return shmSize;
}