summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qwslock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/embedded/qwslock.cpp')
-rw-r--r--src/gui/embedded/qwslock.cpp67
1 files changed, 66 insertions, 1 deletions
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
index c14f50b..f9ea000 100644
--- a/src/gui/embedded/qwslock.cpp
+++ b/src/gui/embedded/qwslock.cpp
@@ -45,12 +45,15 @@
#include "qwssignalhandler_p.h"
+#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/sem.h>
+#endif
#include <sys/time.h>
#include <time.h>
#ifdef Q_OS_LINUX
@@ -66,6 +69,12 @@ QT_BEGIN_NAMESPACE
#error QWSLock currently requires semaphores
#endif
+#ifdef QT_POSIX_IPC
+#include <QtCore/QAtomicInt>
+
+static QBasicAtomicInt localUniqueId = Q_BASIC_ATOMIC_INITIALIZER(1);
+#endif
+
QWSLock::QWSLock(int id) : semId(id)
{
static unsigned short initialValues[3] = { 1, 1, 0 };
@@ -74,6 +83,7 @@ QWSLock::QWSLock(int id) : semId(id)
QWSSignalHandler::instance()->addWSLock(this);
#endif
+#ifndef QT_POSIX_IPC
if (semId == -1) {
semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
if (semId == -1) {
@@ -88,6 +98,30 @@ QWSLock::QWSLock(int id) : semId(id)
qFatal("Unable to initialize semaphores");
}
}
+#else
+ sems[0] = sems[1] = sems[2] = SEM_FAILED;
+ owned = false;
+
+ if (semId == -1) {
+ // ### generate really unique IDs
+ semId = (getpid() << 16) + (localUniqueId.fetchAndAddRelaxed(1) % ushort(-1));
+ owned = true;
+ }
+
+ QByteArray pfx = "/qwslock_" + QByteArray::number(semId, 16) + '_';
+ QByteArray keys[3] = { pfx + "BackingStore", pfx + "Communication", pfx + "RegionEvent" };
+ for (int i = 0; i < 3; ++i) {
+ if (owned)
+ sem_unlink(keys[i].constData());
+ do {
+ sems[i] = sem_open(keys[i].constData(), (owned ? O_CREAT : 0), 0666, initialValues[i]);
+ } while (sems[i] == SEM_FAILED && errno == EINTR);
+ if (sems[i] == SEM_FAILED) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to %s semaphore", (owned ? "create" : "open"));
+ }
+ }
+#endif
lockCount[0] = lockCount[1] = 0;
}
@@ -99,10 +133,27 @@ QWSLock::~QWSLock()
#endif
if (semId != -1) {
+#ifndef QT_POSIX_IPC
qt_semun semval;
semval.val = 0;
semctl(semId, 0, IPC_RMID, semval);
semId = -1;
+#else
+ // emulate the SEM_UNDO behavior for the BackingStore lock
+ while (hasLock(BackingStore))
+ unlock(BackingStore);
+
+ QByteArray pfx = "/qwslock_" + QByteArray::number(semId, 16) + '_';
+ QByteArray keys[3] = { pfx + "BackingStore", pfx + "Communication", pfx + "RegionEvent" };
+ for (int i = 0; i < 3; ++i) {
+ if (sems[i] != SEM_FAILED) {
+ sem_close(sems[i]);
+ sems[i] = SEM_FAILED;
+ }
+ if (owned)
+ sem_unlink(keys[i].constData());
+ }
+#endif
}
}
@@ -110,6 +161,7 @@ bool QWSLock::up(unsigned short semNum)
{
int ret;
+#ifndef QT_POSIX_IPC
sembuf sops = { semNum, 1, 0 };
// As the BackingStore lock is a mutex, and only one process may own
// the lock, it's safe to use SEM_UNDO. On the other hand, the
@@ -119,6 +171,9 @@ bool QWSLock::up(unsigned short semNum)
sops.sem_flg |= SEM_UNDO;
EINTR_LOOP(ret, semop(semId, &sops, 1));
+#else
+ ret = sem_post(sems[semNum]);
+#endif
if (ret == -1) {
qDebug("QWSLock::up(): %s", strerror(errno));
return false;
@@ -131,6 +186,7 @@ bool QWSLock::down(unsigned short semNum, int)
{
int ret;
+#ifndef QT_POSIX_IPC
sembuf sops = { semNum, -1, 0 };
// As the BackingStore lock is a mutex, and only one process may own
// the lock, it's safe to use SEM_UNDO. On the other hand, the
@@ -140,6 +196,9 @@ bool QWSLock::down(unsigned short semNum, int)
sops.sem_flg |= SEM_UNDO;
EINTR_LOOP(ret, semop(semId, &sops, 1));
+#else
+ EINTR_LOOP(ret, sem_wait(sems[semNum]));
+#endif
if (ret == -1) {
qDebug("QWSLock::down(): %s", strerror(errno));
return false;
@@ -150,7 +209,13 @@ bool QWSLock::down(unsigned short semNum, int)
int QWSLock::getValue(unsigned short semNum) const
{
- int ret = semctl(semId, semNum, GETVAL, 0);
+ int ret;
+#ifndef QT_POSIX_IPC
+ ret = semctl(semId, semNum, GETVAL, 0);
+#else
+ if (sem_getvalue(sems[semNum], &ret) == -1)
+ ret = -1;
+#endif
if (ret == -1)
qDebug("QWSLock::getValue(): %s", strerror(errno));
return ret;