diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-06 12:48:55 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-06 12:48:55 (GMT) |
commit | 72bd10eed1f15d8ef3c233acb51212f18bc02f35 (patch) | |
tree | a9e69cb8754ca771a42baa021c67d5f4d892b924 /src/gui/embedded | |
parent | 6cc648cd21b31c79660661ca986e488215c6b846 (diff) | |
parent | 5786c9c3d320fbd5854b883155ade2e834d0e32b (diff) | |
download | Qt-72bd10eed1f15d8ef3c233acb51212f18bc02f35.zip Qt-72bd10eed1f15d8ef3c233acb51212f18bc02f35.tar.gz Qt-72bd10eed1f15d8ef3c233acb51212f18bc02f35.tar.bz2 |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team: (46 commits)
Fixed compile of tst_qscriptextensionplugin on some Windows configurations
drop the SysV semaphores -specific code out from QWSSignalHandler
minor refactoring of the QWSLock class
simplify the code by using the EINTR_LOOP macro
simplify the semaphores initialization
minor refactoring of the QLock class
add a warning on an incorrect usage of QLock
make sure we really clear all locks
fix build with QT_NO_QWS_SIGNALHANDLER
use a printErr() function instead of std::cerr like in lupdate
Re-apply licenseheader text in source files for qt4.8
Fix build in C++0x mode
skip the ipv6 Host checking for the moment, since it fails on Windows XP. will fix later
Added some of my Qt 4.8 changes to the changelog
remove duplicate message
Update bearer startup code in network autotests
symbian socket engine: share ip address conversion code
fix "Host" header of ipv6 URLs in QNAM
uic: Use QString::fromUtf8 for QUrl properties.
license header check: fix exception for URL TLD table
...
Diffstat (limited to 'src/gui/embedded')
-rw-r--r-- | src/gui/embedded/qlock.cpp | 142 | ||||
-rw-r--r-- | src/gui/embedded/qmousepc_qws.cpp | 2 | ||||
-rw-r--r-- | src/gui/embedded/qscreenlinuxfb_qws.cpp | 5 | ||||
-rw-r--r-- | src/gui/embedded/qwslock.cpp | 185 | ||||
-rw-r--r-- | src/gui/embedded/qwslock_p.h | 14 | ||||
-rw-r--r-- | src/gui/embedded/qwssignalhandler.cpp | 52 | ||||
-rw-r--r-- | src/gui/embedded/qwssignalhandler_p.h | 22 |
7 files changed, 190 insertions, 232 deletions
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/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/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; |