diff options
| author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-23 11:11:39 (GMT) |
|---|---|---|
| committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-23 11:11:39 (GMT) |
| commit | d29adf474c694d77ef136a75717f10398f76f7fb (patch) | |
| tree | 51cad9bfa91f074277409837e0739272b957eb0b /src/gui/embedded/qwssharedmemory.cpp | |
| parent | aae54f2fc238b7162336d71c61dfb01fd425b36f (diff) | |
| parent | 2d930fdabccad6bfbbd0075610a302027c8d499b (diff) | |
| download | Qt-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.cpp | 89 |
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; } |
