summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/embedded')
-rw-r--r--src/gui/embedded/qkbd_qws.cpp2
-rw-r--r--src/gui/embedded/qkbdum_qws.cpp2
-rw-r--r--src/gui/embedded/qlock.cpp142
-rw-r--r--src/gui/embedded/qmousepc_qws.cpp2
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.cpp5
-rw-r--r--src/gui/embedded/qwindowsystem_qws.cpp26
-rw-r--r--src/gui/embedded/qwslock.cpp185
-rw-r--r--src/gui/embedded/qwslock_p.h14
-rw-r--r--src/gui/embedded/qwssharedmemory.cpp120
-rw-r--r--src/gui/embedded/qwssharedmemory_p.h34
-rw-r--r--src/gui/embedded/qwssignalhandler.cpp52
-rw-r--r--src/gui/embedded/qwssignalhandler_p.h22
12 files changed, 251 insertions, 355 deletions
diff --git a/src/gui/embedded/qkbd_qws.cpp b/src/gui/embedded/qkbd_qws.cpp
index 77ae47b..5edc4d9 100644
--- a/src/gui/embedded/qkbd_qws.cpp
+++ b/src/gui/embedded/qkbd_qws.cpp
@@ -225,7 +225,7 @@ bool QWSKbPrivate::loadKeymap(const QString &file)
ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size;
if (ds.status() != QDataStream::Ok || qmap_magic != QWSKeyboard::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) {
- qWarning("'%s' is ot a valid.qmap keymap file.", qPrintable(file));
+ qWarning("'%s' is not a valid .qmap keymap file.", qPrintable(file));
return false;
}
diff --git a/src/gui/embedded/qkbdum_qws.cpp b/src/gui/embedded/qkbdum_qws.cpp
index 4fbe03e..97561b5 100644
--- a/src/gui/embedded/qkbdum_qws.cpp
+++ b/src/gui/embedded/qkbdum_qws.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qkbdum_qws.h"
-#include "qvfbhdr.h"
#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_UM)
@@ -55,6 +54,7 @@
#include <qwindowsystem_qws.h>
#include <qsocketnotifier.h>
#include "qplatformdefs.h"
+#include "qvfbhdr.h"
QT_BEGIN_NAMESPACE
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
index bb442e4..ac15431 100644
--- a/src/gui/embedded/qlock.cpp
+++ b/src/gui/embedded/qlock.cpp
@@ -99,7 +99,6 @@ QT_END_NAMESPACE
#endif
#include <string.h>
#include <errno.h>
-#include <qdebug.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -138,8 +137,6 @@ public:
*/
/*!
- \fn QLock::QLock(const QString &filename, char id, bool create)
-
Creates a lock. \a filename is the file path of the Unix-domain
socket the \l{Qt for Embedded Linux} client is using. \a id is the name of the
particular lock to be created on that socket. If \a create is true
@@ -147,76 +144,79 @@ public:
create is false the lock should exist already (as the Qt for Embedded Linux
client expects).
*/
-
QLock::QLock(const QString &filename, char id, bool create)
{
data = new QLockData;
data->count = 0;
#ifdef Q_NO_SEMAPHORE
- data->file = QString(filename+id).toLocal8Bit().constData();
- for(int x = 0; x < 2; x++) {
- data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
- if(data->id != -1 || !create) {
+ data->file = filename.toLocal8Bit() + id;
+ for (int x = 0; x < 2; ++x) {
+ data->id = QT_OPEN(data->file.constData(), O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
+ if (data->id != -1 || !create) {
data->owned = x;
break;
}
}
#else
key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
- data->id = semget(semkey,0,0);
+ data->id = semget(semkey, 0, 0);
data->owned = create;
if (create) {
- qt_semun arg; arg.val = 0;
+ qt_semun arg;
+ arg.val = 0;
if (data->id != -1)
- semctl(data->id,0,IPC_RMID,arg);
- data->id = semget(semkey,1,IPC_CREAT|0600);
+ semctl(data->id, 0, IPC_RMID, arg);
+ data->id = semget(semkey, 1, IPC_CREAT | 0600);
arg.val = MAX_LOCKS;
- semctl(data->id,0,SETVAL,arg);
-
- QWSSignalHandler::instance()->addSemaphore(data->id);
+ semctl(data->id, 0, SETVAL, arg);
}
#endif
- if (data->id == -1) {
- int eno = errno;
- qWarning("Cannot %s semaphore %s '%c'", (create ? "create" : "get"),
- qPrintable(filename), id);
- qDebug() << "Error" << eno << strerror(eno);
+ if (!isValid()) {
+ qWarning("QLock::QLock: Cannot %s semaphore %s '%c' (%d, %s)",
+ (create ? "create" : "get"), qPrintable(filename), id,
+ errno, strerror(errno));
}
+
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addLock(this);
+#endif
}
/*!
- \fn QLock::~QLock()
-
Destroys a lock
*/
-
QLock::~QLock()
{
- if (locked())
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->removeLock(this);
+#endif
+
+ while (locked())
unlock();
#ifdef Q_NO_SEMAPHORE
- if(isValid()) {
+ if (isValid())
QT_CLOSE(data->id);
- if(data->owned)
- unlink(data->file);
- }
+#endif
+ if (data->owned) {
+#ifdef Q_NO_SEMAPHORE
+ unlink(data->file.constData());
#else
- if(data->owned)
- QWSSignalHandler::instance()->removeSemaphore(data->id);
+ qt_semun semval;
+ semval.val = 0;
+ semctl(data->id, 0, IPC_RMID, semval);
#endif
+ }
delete data;
+ data = 0;
}
/*!
- \fn bool QLock::isValid() const
-
Returns true if the lock constructor was successful; returns false if
the lock could not be created or was not available to connect to.
*/
-
bool QLock::isValid() const
{
- return (data->id != -1);
+ return data && data->id != -1;
}
/*!
@@ -230,96 +230,72 @@ bool QLock::isValid() const
will only be unlocked after a corresponding number of unlock()
calls.
*/
-
void QLock::lock(Type t)
{
if (!data->count) {
+ type = t;
+
+ int rv;
#ifdef Q_NO_SEMAPHORE
- int op = LOCK_SH;
- if(t == Write)
- op = LOCK_EX;
- for(int rv=1; rv;) {
- rv = flock(data->id, op);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
+ int op = type == Write ? LOCK_EX : LOCK_SH;
+
+ EINTR_LOOP(rv, flock(data->id, op));
#else
sembuf sops;
sops.sem_num = 0;
+ sops.sem_op = type == Write ? -MAX_LOCKS : -1;
sops.sem_flg = SEM_UNDO;
- if (t == Write) {
- sops.sem_op = -MAX_LOCKS;
- type = Write;
- } else {
- sops.sem_op = -1;
- type = Read;
- }
-
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
+ EINTR_LOOP(rv, semop(data->id, &sops, 1));
#endif
+ if (rv == -1) {
+ qDebug("QLock::lock(): %s", strerror(errno));
+ return;
+ }
+ } else if (type == Read && t == Write) {
+ qDebug("QLock::lock(): Attempt to lock for write while locked for read");
}
data->count++;
}
/*!
- \fn void QLock::unlock()
-
Unlocks the semaphore. If other processes were blocking waiting to
lock() the semaphore, one of them will wake up and succeed in
- lock()ing.
+ locking.
*/
-
void QLock::unlock()
{
- if(data->count) {
+ if (data->count) {
data->count--;
- if(!data->count) {
+ if (!data->count) {
+ int rv;
#ifdef Q_NO_SEMAPHORE
- for(int rv=1; rv;) {
- rv = flock(data->id, LOCK_UN);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
+ EINTR_LOOP(rv, flock(data->id, LOCK_UN));
#else
sembuf sops;
sops.sem_num = 0;
- sops.sem_op = 1;
+ sops.sem_op = type == Write ? MAX_LOCKS : 1;
sops.sem_flg = SEM_UNDO;
- if (type == Write)
- sops.sem_op = MAX_LOCKS;
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop unlock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
+ EINTR_LOOP(rv, semop(data->id, &sops, 1));
#endif
+ if (rv == -1)
+ qDebug("QLock::unlock(): %s", strerror(errno));
}
} else {
- qDebug("Unlock without corresponding lock");
+ qDebug("QLock::unlock(): Unlock without corresponding lock");
}
}
/*!
- \fn bool QLock::locked() const
-
Returns true if the lock is currently held by the current process;
otherwise returns false.
*/
-
bool QLock::locked() const
{
- return (data->count > 0);
+ return isValid() && data->count > 0;
}
QT_END_NAMESPACE
#endif // QT_NO_QWS_MULTIPROCESS
-
diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp
index 5d3b182..c22cab9 100644
--- a/src/gui/embedded/qmousepc_qws.cpp
+++ b/src/gui/embedded/qmousepc_qws.cpp
@@ -261,7 +261,7 @@ public:
usleep(50000);
QT_WRITE(fd,"@EeI!",5);
usleep(10000);
- static const char ibuf[] = { 246, 244 };
+ static const unsigned char ibuf[] = { 246, 244 };
QT_WRITE(fd,ibuf,1);
QT_WRITE(fd,ibuf+1,1);
if (tcflush(fd,TCIOFLUSH) == -1) {
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp
index 67c8a31..4b41b5b 100644
--- a/src/gui/embedded/qscreenlinuxfb_qws.cpp
+++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp
@@ -110,7 +110,9 @@ QLinuxFbScreenPrivate::QLinuxFbScreenPrivate()
#endif
ttyfd(-1), oldKdMode(KD_TEXT)
{
+#ifndef QT_NO_QWS_SIGNALHANDLER
QWSSignalHandler::instance()->addObject(this);
+#endif
}
QLinuxFbScreenPrivate::~QLinuxFbScreenPrivate()
@@ -263,6 +265,9 @@ QLinuxFbScreen::QLinuxFbScreen(int display_id)
QLinuxFbScreen::~QLinuxFbScreen()
{
+#ifdef QT_NO_QWS_SIGNALHANDLER
+ delete d_ptr;
+#endif
}
/*!
diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp
index 0e4e27c..36802a8 100644
--- a/src/gui/embedded/qwindowsystem_qws.cpp
+++ b/src/gui/embedded/qwindowsystem_qws.cpp
@@ -2494,7 +2494,7 @@ QWSWindow *QWSServer::windowAt(const QPoint& pos)
}
#ifndef QT_NO_QWS_KEYBOARD
-static int keyUnicode(int keycode)
+static inline int keyUnicode(int keycode)
{
int code = 0xffff;
@@ -2550,18 +2550,16 @@ void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers mod
void QWSServerPrivate::sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
bool isPress, bool autoRepeat)
{
+ QWSWindow *win = keyboardGrabber ? keyboardGrabber : qwsServerPrivate->focusw;
- QWSKeyEvent event;
- QWSWindow *win = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
-
- event.simpleData.window = win ? win->winId() : 0;
-
- event.simpleData.unicode =
#ifndef QT_NO_QWS_KEYBOARD
- unicode < 0 ? keyUnicode(keycode) :
+ if (unicode < 0)
+ unicode = keyUnicode(keycode);
#endif
- unicode;
+
+ QWSKeyEvent event;
+ event.simpleData.window = win ? win->winId() : 0;
+ event.simpleData.unicode = unicode;
event.simpleData.keycode = keycode;
event.simpleData.modifiers = modifiers;
event.simpleData.is_press = isPress;
@@ -4127,11 +4125,11 @@ void QWSServer::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers
#endif
// If we press a key and it's going to be blocked, wake up the screen
- if ( block && isPress )
- qwsServerPrivate->_q_screenSaverWake();
-
- if ( block )
+ if (block) {
+ if (isPress)
+ qwsServerPrivate->_q_screenSaverWake();
return;
+ }
if (keyFilters) {
for (int i = 0; i < keyFilters->size(); ++i) {
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
index 0d65b61..c14f50b 100644
--- a/src/gui/embedded/qwslock.cpp
+++ b/src/gui/embedded/qwslock.cpp
@@ -45,8 +45,6 @@
#include "qwssignalhandler_p.h"
-#include <qglobal.h>
-#include <qdebug.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -68,164 +66,141 @@ QT_BEGIN_NAMESPACE
#error QWSLock currently requires semaphores
#endif
-QWSLock::QWSLock()
+QWSLock::QWSLock(int id) : semId(id)
{
- semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
+ static unsigned short initialValues[3] = { 1, 1, 0 };
- if (semId == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to create semaphore");
- }
- QWSSignalHandler::instance()->addSemaphore(semId);
-
- qt_semun semval;
- semval.val = 1;
-
- if (semctl(semId, BackingStore, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize backingstore semaphore");
- }
- lockCount[BackingStore] = 0;
-
- if (semctl(semId, Communication, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize communication semaphore");
- }
- lockCount[Communication] = 0;
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addWSLock(this);
+#endif
- semval.val = 0;
- if (semctl(semId, RegionEvent, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize region event semaphore");
+ if (semId == -1) {
+ semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
+ if (semId == -1) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to create semaphore");
+ }
+
+ qt_semun semval;
+ semval.array = initialValues;
+ if (semctl(semId, 0, SETALL, semval) == -1) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to initialize semaphores");
+ }
}
-}
-QWSLock::QWSLock(int id)
-{
- semId = id;
- QWSSignalHandler::instance()->addSemaphore(semId);
lockCount[0] = lockCount[1] = 0;
}
QWSLock::~QWSLock()
{
- if (semId == -1)
- return;
- QWSSignalHandler::instance()->removeSemaphore(semId);
-}
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->removeWSLock(this);
+#endif
-static bool forceLock(int semId, int semNum, int)
-{
- int ret;
- do {
- 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
- // Communication lock is locked by the client but unlocked by the
- // server and therefore can't use SEM_UNDO.
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::lock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+ if (semId != -1) {
+ qt_semun semval;
+ semval.val = 0;
+ semctl(semId, 0, IPC_RMID, semval);
+ semId = -1;
+ }
}
-static bool up(int semId, int semNum)
+bool QWSLock::up(unsigned short semNum)
{
int ret;
- do {
- sembuf sops = { semNum, 1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::up: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+
+ 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
+ // Communication lock is locked by the client but unlocked by the
+ // server and therefore can't use SEM_UNDO.
+ if (semNum == BackingStore)
+ sops.sem_flg |= SEM_UNDO;
+
+ EINTR_LOOP(ret, semop(semId, &sops, 1));
+ if (ret == -1) {
+ qDebug("QWSLock::up(): %s", strerror(errno));
+ return false;
+ }
+
+ return true;
}
-static bool down(int semId, int semNum)
+bool QWSLock::down(unsigned short semNum, int)
{
int ret;
- do {
- sembuf sops = { semNum, -1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::down: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+
+ 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
+ // Communication lock is locked by the client but unlocked by the
+ // server and therefore can't use SEM_UNDO.
+ if (semNum == BackingStore)
+ sops.sem_flg |= SEM_UNDO;
+
+ EINTR_LOOP(ret, semop(semId, &sops, 1));
+ if (ret == -1) {
+ qDebug("QWSLock::down(): %s", strerror(errno));
+ return false;
+ }
+
+ return true;
}
-static int getValue(int semId, int semNum)
+int QWSLock::getValue(unsigned short semNum) const
{
- int ret;
- do {
- ret = semctl(semId, semNum, GETVAL, 0);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::getValue: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
+ int ret = semctl(semId, semNum, GETVAL, 0);
+ if (ret == -1)
+ qDebug("QWSLock::getValue(): %s", strerror(errno));
return ret;
}
bool QWSLock::lock(LockType type, int timeout)
{
if (type == RegionEvent)
- return up(semId, RegionEvent);
+ return up(type);
- if (hasLock(type)) {
+ if (lockCount[type] > 0) {
++lockCount[type];
return true;
}
- if (!forceLock(semId, type, timeout))
- return false;
- ++lockCount[type];
- return true;
+ if (down(type, timeout)) {
+ ++lockCount[type];
+ return true;
+ }
+
+ return false;
}
bool QWSLock::hasLock(LockType type)
{
if (type == RegionEvent)
- return (getValue(semId, RegionEvent) == 0);
+ return getValue(type) == 0;
- return (lockCount[type] > 0);
+ return lockCount[type] > 0;
}
void QWSLock::unlock(LockType type)
{
if (type == RegionEvent) {
- down(semId, RegionEvent);
+ down(type, -1);
return;
}
- if (hasLock(type)) {
+ if (lockCount[type] > 0) {
--lockCount[type];
- if (hasLock(type))
+ if (lockCount[type] > 0)
return;
}
- const int semNum = type;
- int ret;
- do {
- sembuf sops = {semNum, 1, 0};
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::unlock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
+ up(type);
}
bool QWSLock::wait(LockType type, int timeout)
{
- bool ok = forceLock(semId, type, timeout);
+ bool ok = down(type, timeout);
if (ok)
unlock(type);
return ok;
diff --git a/src/gui/embedded/qwslock_p.h b/src/gui/embedded/qwslock_p.h
index 9a7f279..d020b22 100644
--- a/src/gui/embedded/qwslock_p.h
+++ b/src/gui/embedded/qwslock_p.h
@@ -55,17 +55,16 @@
#include <qglobal.h>
-QT_BEGIN_NAMESPACE
-
#ifndef QT_NO_QWS_MULTIPROCESS
+QT_BEGIN_NAMESPACE
+
class QWSLock
{
public:
enum LockType { BackingStore, Communication, RegionEvent };
- QWSLock();
- QWSLock(int lockId);
+ QWSLock(int lockId = -1);
~QWSLock();
bool lock(LockType type, int timeout = -1);
@@ -75,11 +74,16 @@ public:
int id() const { return semId; }
private:
+ bool up(unsigned short semNum);
+ bool down(unsigned short semNum, int timeout);
+ int getValue(unsigned short semNum) const;
+
int semId;
int lockCount[2];
};
-
QT_END_NAMESPACE
+
#endif // QT_NO_QWS_MULTIPROCESS
+
#endif // QWSLOCK_P_H
diff --git a/src/gui/embedded/qwssharedmemory.cpp b/src/gui/embedded/qwssharedmemory.cpp
index 66bedee..a677626 100644
--- a/src/gui/embedded/qwssharedmemory.cpp
+++ b/src/gui/embedded/qwssharedmemory.cpp
@@ -43,51 +43,51 @@
#if !defined(QT_NO_QWS_MULTIPROCESS)
+#include <sys/types.h>
+#include <sys/ipc.h>
#include <sys/shm.h>
+//#define QT_SHM_DEBUG
+
QT_BEGIN_NAMESPACE
QWSSharedMemory::QWSSharedMemory()
- : shmBase(0), shmSize(0), character(0), shmId(-1), key(-1)
+ : shmId(-1), shmBase(0), shmSize(0)
{
}
-
QWSSharedMemory::~QWSSharedMemory()
{
detach();
}
-/*
- man page says:
- 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 spec-
- ify this behaviour and many other implementations do not support it.
-*/
-
bool QWSSharedMemory::create(int size)
{
if (shmId != -1)
detach();
- shmId = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
+ shmId = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600);
if (shmId == -1) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create allocating shared memory");
+ perror("QWSSharedMemory::create():");
qWarning("Error allocating shared memory of size %d", size);
#endif
return false;
}
- shmBase = shmat(shmId,0,0);
+ 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);
- if (shmBase == (void*)-1) {
+ if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create attaching to shared memory");
+ perror("QWSSharedMemory::create():");
qWarning("Error attaching to shared memory id %d", shmId);
#endif
- shmBase = 0;
+ detach();
return false;
}
+
return true;
}
@@ -95,91 +95,49 @@ bool QWSSharedMemory::attach(int id)
{
if (shmId == id)
return id != -1;
- if (shmId != -1)
- detach();
- shmBase = shmat(id,0,0);
- if (shmBase == (void*)-1) {
+ detach();
+
+ if (id == -1)
+ return false;
+
+ shmId = id;
+ shmBase = shmat(shmId, 0, 0);
+ if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::attach attaching to shared memory");
- qWarning("Error attaching to shared memory 0x%x of size %d",
- id, size());
+ perror("QWSSharedMemory::attach():");
+ qWarning("Error attaching to shared memory id %d", shmId);
#endif
- shmBase = 0;
+ detach();
return false;
}
- shmId = id;
+
return true;
}
-
-void QWSSharedMemory::detach ()
+void QWSSharedMemory::detach()
{
- if (!shmBase)
- return;
- shmdt (shmBase);
+ if (shmBase && shmBase != (void*)-1)
+ shmdt(shmBase);
shmBase = 0;
shmSize = 0;
shmId = -1;
}
-void QWSSharedMemory::setPermissions (mode_t mode)
+int QWSSharedMemory::size() const
{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- shm.shm_perm.mode = mode;
- shmctl (shmId, IPC_SET, &shm);
-}
-
-int QWSSharedMemory::size () const
-{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- return shm.shm_segsz;
-}
+ if (shmId == -1)
+ return 0;
+ if (!shmSize) {
+ struct shmid_ds shm;
+ shmctl(shmId, IPC_STAT, &shm);
+ const_cast<QWSSharedMemory *>(this)->shmSize = shm.shm_segsz;
+ }
-// old API
-
-
-
-QWSSharedMemory::QWSSharedMemory (int size, const QString &filename, char c)
-{
- shmSize = size;
- shmFile = filename;
- shmBase = 0;
- shmId = -1;
- character = c;
- key = ftok (shmFile.toLatin1().constData(), c);
-}
-
-
-
-bool QWSSharedMemory::create ()
-{
- shmId = shmget (key, shmSize, IPC_CREAT | 0666);
- return (shmId != -1);
-}
-
-void QWSSharedMemory::destroy ()
-{
- if (shmId != -1)
- shmctl(shmId, IPC_RMID, 0);
-}
-
-bool QWSSharedMemory::attach ()
-{
- if (shmId == -1)
- shmId = shmget (key, shmSize, 0);
-
- shmBase = shmat (shmId, 0, 0);
- if ((long)shmBase == -1)
- shmBase = 0;
-
- return (long)shmBase != 0;
+ return shmSize;
}
-
QT_END_NAMESPACE
#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssharedmemory_p.h b/src/gui/embedded/qwssharedmemory_p.h
index 31e69c4..f3ce241 100644
--- a/src/gui/embedded/qwssharedmemory_p.h
+++ b/src/gui/embedded/qwssharedmemory_p.h
@@ -53,49 +53,31 @@
// We mean it.
//
-#include "qplatformdefs.h"
-#include "QtCore/qstring.h"
+#include <qplatformdefs.h>
QT_BEGIN_NAMESPACE
#if !defined(QT_NO_QWS_MULTIPROCESS)
-class QWSSharedMemory {
+class QWSSharedMemory
+{
public:
-
QWSSharedMemory();
~QWSSharedMemory();
- void setPermissions(mode_t mode);
- int size() const;
- void *address() { return shmBase; }
-
- int id() const { return shmId; }
-
- void detach();
-
bool create(int size);
bool attach(int id);
+ void detach();
- //bool create(int size, const QString &filename, char c = 'Q');
- //bool attach(const QString &filename, char c = 'Q');
-// old API
-
- QWSSharedMemory(int, const QString &, char c = 'Q');
- void * base() { return address(); }
-
- bool create();
- void destroy();
+ int id() const { return shmId; }
- bool attach();
+ void *address() const { return shmBase; }
+ int size() const;
private:
+ int shmId;
void *shmBase;
int shmSize;
- QString shmFile;
- char character;
- int shmId;
- key_t key;
};
#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp
index 730dbae..b13a57d 100644
--- a/src/gui/embedded/qwssignalhandler.cpp
+++ b/src/gui/embedded/qwssignalhandler.cpp
@@ -43,13 +43,10 @@
#ifndef QT_NO_QWS_SIGNALHANDLER
-#include <sys/types.h>
-#ifndef QT_NO_QWS_MULTIPROCESS
-# include <sys/ipc.h>
-# include <sys/sem.h>
+#include "qlock_p.h"
+#include "qwslock_p.h"
-# include <private/qcore_unix_p.h>
-#endif
+#include <sys/types.h>
#include <signal.h>
QT_BEGIN_NAMESPACE
@@ -87,42 +84,33 @@ QWSSignalHandler::QWSSignalHandler()
QWSSignalHandler::~QWSSignalHandler()
{
-#ifndef QT_NO_QWS_MULTIPROCESS
- while (!semaphores.isEmpty())
- removeSemaphore(semaphores.last());
-#endif
+ clear();
}
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSSignalHandler::removeSemaphore(int semno)
+void QWSSignalHandler::clear()
{
- const int index = semaphores.lastIndexOf(semno);
- if (index != -1) {
- qt_semun semval;
- semval.val = 0;
- semctl(semaphores.at(index), 0, IPC_RMID, semval);
- semaphores.remove(index);
- }
+#if !defined(QT_NO_QWS_MULTIPROCESS)
+ // it is safe to call d-tors directly here since, on normal exit,
+ // lists should be empty; otherwise, we don't care about semi-alive objects
+ // and the only important thing here is to unregister the system semaphores.
+ while (!locks.isEmpty())
+ locks.takeLast()->~QLock();
+ while (!wslocks.isEmpty())
+ wslocks.takeLast()->~QWSLock();
+#endif
+ objects.clear();
}
-#endif // QT_NO_QWS_MULTIPROCESS
void QWSSignalHandler::handleSignal(int signum)
{
QWSSignalHandler *h = instance();
-
- signal(signum, h->oldHandlers[signum]);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- qt_semun semval;
- semval.val = 0;
- for (int i = 0; i < h->semaphores.size(); ++i)
- semctl(h->semaphores.at(i), 0, IPC_RMID, semval);
-#endif
-
- h->objects.clear();
+ if (h) {
+ signal(signum, h->oldHandlers[signum]);
+ h->clear();
+ }
raise(signum);
}
QT_END_NAMESPACE
-#endif // QT_QWS_NO_SIGNALHANDLER
+#endif // QT_NO_QWS_SIGNALHANDLER
diff --git a/src/gui/embedded/qwssignalhandler_p.h b/src/gui/embedded/qwssignalhandler_p.h
index dda9c76..217eda1 100644
--- a/src/gui/embedded/qwssignalhandler_p.h
+++ b/src/gui/embedded/qwssignalhandler_p.h
@@ -57,14 +57,17 @@
#ifndef QT_NO_QWS_SIGNALHANDLER
-#include <QtCore/qmap.h>
-#include <QtCore/qvector.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
#include <QtCore/qobjectcleanuphandler.h>
QT_BEGIN_NAMESPACE
typedef void (*qt_sighandler_t)(int);
+class QLock;
+class QWSLock;
+
class QWSSignalHandlerPrivate;
class Q_GUI_EXPORT QWSSignalHandler
@@ -75,17 +78,24 @@ public:
~QWSSignalHandler();
#ifndef QT_NO_QWS_MULTIPROCESS
- inline void addSemaphore(int semno) { semaphores.append(semno); }
- void removeSemaphore(int semno);
+ inline void addLock(QLock *lock) { locks.append(lock); }
+ inline void removeLock(QLock *lock) { locks.removeOne(lock); }
+ inline void addWSLock(QWSLock *wslock) { wslocks.append(wslock); }
+ inline void removeWSLock(QWSLock *wslock) { wslocks.removeOne(wslock); }
#endif
inline void addObject(QObject *object) { (void)objects.add(object); }
private:
QWSSignalHandler();
+
+ void clear();
+
static void handleSignal(int signal);
- QMap<int, qt_sighandler_t> oldHandlers;
+
+ QHash<int, qt_sighandler_t> oldHandlers;
#ifndef QT_NO_QWS_MULTIPROCESS
- QVector<int> semaphores;
+ QList<QLock *> locks;
+ QList<QWSLock *> wslocks;
#endif
QObjectCleanupHandler objects;