From 0b92d6cc61a18ae18d254ac6ee463e74cb570db4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 1 Jun 2011 12:34:59 +0200 Subject: use a printErr() function instead of std::cerr like in lupdate --- tools/linguist/lrelease/main.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index b1beec8..8d2cf4a 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -55,8 +55,6 @@ #include #include -#include - QT_USE_NAMESPACE #ifdef QT_BOOTSTRAPPED @@ -84,6 +82,12 @@ static void printOut(const QString & out) stream << out; } +static void printErr(const QString & out) +{ + QTextStream stream(stderr); + stream << out; +} + static void printUsage() { printOut(LR::tr( @@ -119,7 +123,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo ConversionData cd; bool ok = tor.load(tsFileName, cd, QLatin1String("auto")); if (!ok) { - std::cerr << qPrintable(LR::tr("lrelease error: %1").arg(cd.error())); + printErr(LR::tr("lrelease error: %1").arg(cd.error())); } else { if (!cd.errors().isEmpty()) printOut(cd.error()); @@ -143,7 +147,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, QFile file(qmFileName); if (!file.open(QIODevice::WriteOnly)) { - std::cerr << qPrintable(LR::tr("lrelease error: cannot create '%1': %2\n") + printErr(LR::tr("lrelease error: cannot create '%1': %2\n") .arg(qmFileName, file.errorString())); return false; } @@ -153,7 +157,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, file.close(); if (!ok) { - std::cerr << qPrintable(LR::tr("lrelease error: cannot save '%1': %2") + printErr(LR::tr("lrelease error: cannot save '%1': %2") .arg(qmFileName, cd.error())); } else if (!cd.errors().isEmpty()) { printOut(cd.error()); @@ -274,13 +278,13 @@ int main(int argc, char **argv) visitor.setVerbose(cd.isVerbose()); if (!visitor.queryProFile(&pro)) { - std::cerr << qPrintable(LR::tr( + printErr(LR::tr( "lrelease error: cannot read project file '%1'.\n") .arg(inputFile)); continue; } if (!visitor.accept(&pro)) { - std::cerr << qPrintable(LR::tr( + printErr(LR::tr( "lrelease error: cannot process project file '%1'.\n") .arg(inputFile)); continue; @@ -288,7 +292,7 @@ int main(int argc, char **argv) QStringList translations = visitor.values(QLatin1String("TRANSLATIONS")); if (translations.isEmpty()) { - std::cerr << qPrintable(LR::tr( + printErr(LR::tr( "lrelease warning: Met no 'TRANSLATIONS' entry in project file '%1'\n") .arg(inputFile)); } else { -- cgit v0.12 From 9a4d1230b54c15af6f5448c1551c35242b668ccf Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:35 +0200 Subject: fix build with QT_NO_QWS_SIGNALHANDLER Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qlock.cpp | 11 ++++++++++- src/gui/embedded/qscreenlinuxfb_qws.cpp | 5 +++++ src/gui/embedded/qwslock.cpp | 16 +++++++++++++--- src/gui/embedded/qwssignalhandler.cpp | 2 +- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index bb442e4..e7db7e6 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -173,7 +173,9 @@ QLock::QLock(const QString &filename, char id, bool create) arg.val = MAX_LOCKS; semctl(data->id,0,SETVAL,arg); +#ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addSemaphore(data->id); +#endif } #endif if (data->id == -1) { @@ -201,8 +203,15 @@ QLock::~QLock() unlink(data->file); } #else - if(data->owned) + if (data->owned) { +#ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->removeSemaphore(data->id); +#else + qt_semun semval; + semval.val = 0; + semctl(data->id, 0, IPC_RMID, semval); +#endif + } #endif delete data; } 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 a64dc3d..1d9bfb6 100644 --- a/src/gui/embedded/qwslock.cpp +++ b/src/gui/embedded/qwslock.cpp @@ -76,7 +76,9 @@ QWSLock::QWSLock() perror("QWSLock::QWSLock"); qFatal("Unable to create semaphore"); } +#ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addSemaphore(semId); +#endif qt_semun semval; semval.val = 1; @@ -103,15 +105,23 @@ QWSLock::QWSLock() QWSLock::QWSLock(int id) { semId = id; +#ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addSemaphore(semId); +#endif lockCount[0] = lockCount[1] = 0; } QWSLock::~QWSLock() { - if (semId == -1) - return; - QWSSignalHandler::instance()->removeSemaphore(semId); + if (semId != -1) { +#ifndef QT_NO_QWS_SIGNALHANDLER + QWSSignalHandler::instance()->removeSemaphore(semId); +#else + qt_semun semval; + semval.val = 0; + semctl(semId, 0, IPC_RMID, semval); +#endif + } } static bool forceLock(int semId, unsigned short semNum, int) diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp index 730dbae..2a20141 100644 --- a/src/gui/embedded/qwssignalhandler.cpp +++ b/src/gui/embedded/qwssignalhandler.cpp @@ -125,4 +125,4 @@ void QWSSignalHandler::handleSignal(int signum) QT_END_NAMESPACE -#endif // QT_QWS_NO_SIGNALHANDLER +#endif // QT_NO_QWS_SIGNALHANDLER -- cgit v0.12 From 02c7d2d114bf2f5fb2a1947e6370046f0141499b Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:36 +0200 Subject: make sure we really clear all locks Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index e7db7e6..8f24e7d 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -194,7 +194,7 @@ QLock::QLock(const QString &filename, char id, bool create) QLock::~QLock() { - if (locked()) + while (locked()) unlock(); #ifdef Q_NO_SEMAPHORE if(isValid()) { -- cgit v0.12 From 8d6e9dcc2eba13647b2c608fc20cf85ae9b99426 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:37 +0200 Subject: add a warning on an incorrect usage of QLock Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qlock.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index 8f24e7d..034f5fb 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -272,6 +272,8 @@ void QLock::lock(Type t) qDebug("Semop lock failure %s",strerror(errno)); } while (rv == -1 && errno == EINTR); #endif + } else if (type == Read && t == Write) { + qDebug("QLock::lock: Attempt to lock for write while locked for read"); } data->count++; } -- cgit v0.12 From e99f8f0db4e427bda280587d32b5e12d114043c4 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:38 +0200 Subject: minor refactoring of the QLock class use EINTR_LOOP macro to simplify the code; code cleanups; minor optimizations; more informative debug strings Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qlock.cpp | 128 ++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 82 deletions(-) diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index 034f5fb..ae18b05 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -99,7 +99,6 @@ QT_END_NAMESPACE #endif #include #include -#include #include // 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,82 +144,75 @@ 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); + semctl(data->id, 0, SETVAL, arg); #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addSemaphore(data->id); #endif } #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)); } } /*! - \fn QLock::~QLock() - Destroys a lock */ - QLock::~QLock() { while (locked()) unlock(); #ifdef Q_NO_SEMAPHORE - if(isValid()) { + if (isValid()) QT_CLOSE(data->id); - if(data->owned) - unlink(data->file); - } -#else +#endif if (data->owned) { -#ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->removeSemaphore(data->id); +#ifdef Q_NO_SEMAPHORE + unlink(data->file.constData()); #else qt_semun semval; semval.val = 0; semctl(data->id, 0, IPC_RMID, semval); + +#ifndef QT_NO_QWS_SIGNALHANDLER + QWSSignalHandler::instance()->removeSemaphore(data->id); #endif - } #endif + } delete data; } /*! - \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); @@ -239,98 +229,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"); + 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 - -- cgit v0.12 From b840d8255196241fa7c2684c0443471330f94046 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:39 +0200 Subject: simplify the semaphores initialization there is no need in 3 separate tests since, for local semaphores, semctl(2) always works. if it's not, well, 1 test is completely enough to check that Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qwslock.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp index 1d9bfb6..ae168df 100644 --- a/src/gui/embedded/qwslock.cpp +++ b/src/gui/embedded/qwslock.cpp @@ -70,8 +70,9 @@ QT_BEGIN_NAMESPACE QWSLock::QWSLock() { - semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666); + static unsigned short initialValues[3] = { 1, 1, 0 }; + semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666); if (semId == -1) { perror("QWSLock::QWSLock"); qFatal("Unable to create semaphore"); @@ -81,25 +82,13 @@ QWSLock::QWSLock() #endif qt_semun semval; - semval.val = 1; - - if (semctl(semId, BackingStore, SETVAL, semval) == -1) { + semval.array = initialValues; + if (semctl(semId, 0, SETALL, semval) == -1) { perror("QWSLock::QWSLock"); - qFatal("Unable to initialize backingstore semaphore"); + qFatal("Unable to initialize semaphores"); } - lockCount[BackingStore] = 0; - if (semctl(semId, Communication, SETVAL, semval) == -1) { - perror("QWSLock::QWSLock"); - qFatal("Unable to initialize communication semaphore"); - } - lockCount[Communication] = 0; - - semval.val = 0; - if (semctl(semId, RegionEvent, SETVAL, semval) == -1) { - perror("QWSLock::QWSLock"); - qFatal("Unable to initialize region event semaphore"); - } + lockCount[0] = lockCount[1] = 0; } QWSLock::QWSLock(int id) -- cgit v0.12 From 4134cb7dfc04ca7721277772c41b678bac6b33a0 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:41 +0200 Subject: simplify the code by using the EINTR_LOOP macro the sembuf structure now initializes out of the loop (nano-opt) Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qwslock.cpp | 72 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp index ae168df..d8996d6 100644 --- a/src/gui/embedded/qwslock.cpp +++ b/src/gui/embedded/qwslock.cpp @@ -116,59 +116,59 @@ QWSLock::~QWSLock() static bool forceLock(int semId, unsigned short 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); + 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; + + EINTR_LOOP(ret, semop(semId, &sops, 1)); + if (ret == -1) { + qDebug("QWSLock::lock(): %s", strerror(errno)); + return false; + } - return (ret != -1); + return true; } static bool up(int semId, 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 }; + + 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, unsigned short semNum) { 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 }; + + 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, unsigned short semNum) { - 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; } @@ -218,7 +218,7 @@ void QWSLock::unlock(LockType type) ret = semop(semId, &sops, 1); if (ret == -1 && errno != EINTR) - qDebug("QWSLock::unlock: %s", strerror(errno)); + qDebug("QWSLock::unlock(): %s", strerror(errno)); } while (ret == -1 && errno == EINTR); } -- cgit v0.12 From 6896244f266becfb5807985c5628c8f0a775ce76 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:42 +0200 Subject: minor refactoring of the QWSLock class unify both constructors in a single one; make the code cleaner and cheaper Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qwslock.cpp | 101 ++++++++++++++++--------------------------- src/gui/embedded/qwslock_p.h | 14 +++--- 2 files changed, 47 insertions(+), 68 deletions(-) diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp index d8996d6..67f8bd8 100644 --- a/src/gui/embedded/qwslock.cpp +++ b/src/gui/embedded/qwslock.cpp @@ -45,8 +45,6 @@ #include "qwssignalhandler_p.h" -#include -#include #include #include #include @@ -68,36 +66,30 @@ QT_BEGIN_NAMESPACE #error QWSLock currently requires semaphores #endif -QWSLock::QWSLock() +QWSLock::QWSLock(int id) : semId(id) { static unsigned short initialValues[3] = { 1, 1, 0 }; - semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666); if (semId == -1) { - perror("QWSLock::QWSLock"); - qFatal("Unable to create semaphore"); - } -#ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->addSemaphore(semId); -#endif + 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"); + qt_semun semval; + semval.array = initialValues; + if (semctl(semId, 0, SETALL, semval) == -1) { + perror("QWSLock::QWSLock"); + qFatal("Unable to initialize semaphores"); + } } lockCount[0] = lockCount[1] = 0; -} -QWSLock::QWSLock(int id) -{ - semId = id; #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addSemaphore(semId); #endif - lockCount[0] = lockCount[1] = 0; } QWSLock::~QWSLock() @@ -113,35 +105,20 @@ QWSLock::~QWSLock() } } -static bool forceLock(int semId, unsigned short semNum, int) +bool QWSLock::up(unsigned short semNum) { int ret; - sembuf sops = { semNum, -1, 0 }; + 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) + if (semNum == BackingStore) sops.sem_flg |= SEM_UNDO; EINTR_LOOP(ret, semop(semId, &sops, 1)); if (ret == -1) { - qDebug("QWSLock::lock(): %s", strerror(errno)); - return false; - } - - return true; -} - -static bool up(int semId, unsigned short semNum) -{ - int ret; - - sembuf sops = { semNum, 1, 0 }; - - EINTR_LOOP(ret, semop(semId, &sops, 1)); - if (ret == -1) { qDebug("QWSLock::up(): %s", strerror(errno)); return false; } @@ -149,11 +126,17 @@ static bool up(int semId, unsigned short semNum) return true; } -static bool down(int semId, unsigned short semNum) +bool QWSLock::down(unsigned short semNum, int) { int ret; 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) { @@ -164,7 +147,7 @@ static bool down(int semId, unsigned short semNum) return true; } -static int getValue(int semId, unsigned short semNum) +int QWSLock::getValue(unsigned short semNum) const { int ret = semctl(semId, semNum, GETVAL, 0); if (ret == -1) @@ -175,56 +158,48 @@ static int getValue(int semId, unsigned short semNum) 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 unsigned short 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 -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 -- cgit v0.12 From 9f71cffea1d5cdac94ae7368ffa7f54183ac33a4 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 1 Jun 2011 16:49:43 +0200 Subject: drop the SysV semaphores -specific code out from QWSSignalHandler it is safe to call the QLock/QWSLock desctructors instead on normal exit where both lists should be empty; on crash, we don't care about semi-alive objects and the only important thing is to unregister the system semaphores. Merge-request: 1237 Reviewed-by: Harald Fernengel --- src/gui/embedded/qlock.cpp | 19 ++++++------- src/gui/embedded/qwslock.cpp | 17 ++++++------ src/gui/embedded/qwssignalhandler.cpp | 50 +++++++++++++---------------------- src/gui/embedded/qwssignalhandler_p.h | 22 ++++++++++----- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index ae18b05..ac15431 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -169,10 +169,6 @@ QLock::QLock(const QString &filename, char id, bool create) data->id = semget(semkey, 1, IPC_CREAT | 0600); arg.val = MAX_LOCKS; semctl(data->id, 0, SETVAL, arg); - -#ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->addSemaphore(data->id); -#endif } #endif if (!isValid()) { @@ -180,6 +176,10 @@ QLock::QLock(const QString &filename, char id, bool create) (create ? "create" : "get"), qPrintable(filename), id, errno, strerror(errno)); } + +#ifndef QT_NO_QWS_SIGNALHANDLER + QWSSignalHandler::instance()->addLock(this); +#endif } /*! @@ -187,6 +187,10 @@ QLock::QLock(const QString &filename, char id, bool create) */ QLock::~QLock() { +#ifndef QT_NO_QWS_SIGNALHANDLER + QWSSignalHandler::instance()->removeLock(this); +#endif + while (locked()) unlock(); #ifdef Q_NO_SEMAPHORE @@ -200,13 +204,10 @@ QLock::~QLock() qt_semun semval; semval.val = 0; semctl(data->id, 0, IPC_RMID, semval); - -#ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->removeSemaphore(data->id); -#endif #endif } delete data; + data = 0; } /*! @@ -215,7 +216,7 @@ QLock::~QLock() */ bool QLock::isValid() const { - return (data->id != -1); + return data && data->id != -1; } /*! diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp index 67f8bd8..c14f50b 100644 --- a/src/gui/embedded/qwslock.cpp +++ b/src/gui/embedded/qwslock.cpp @@ -70,6 +70,10 @@ QWSLock::QWSLock(int id) : semId(id) { static unsigned short initialValues[3] = { 1, 1, 0 }; +#ifndef QT_NO_QWS_SIGNALHANDLER + QWSSignalHandler::instance()->addWSLock(this); +#endif + if (semId == -1) { semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666); if (semId == -1) { @@ -86,22 +90,19 @@ QWSLock::QWSLock(int id) : semId(id) } lockCount[0] = lockCount[1] = 0; - -#ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->addSemaphore(semId); -#endif } QWSLock::~QWSLock() { - if (semId != -1) { #ifndef QT_NO_QWS_SIGNALHANDLER - QWSSignalHandler::instance()->removeSemaphore(semId); -#else + QWSSignalHandler::instance()->removeWSLock(this); +#endif + + if (semId != -1) { qt_semun semval; semval.val = 0; semctl(semId, 0, IPC_RMID, semval); -#endif + semId = -1; } } diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp index 2a20141..b13a57d 100644 --- a/src/gui/embedded/qwssignalhandler.cpp +++ b/src/gui/embedded/qwssignalhandler.cpp @@ -43,13 +43,10 @@ #ifndef QT_NO_QWS_SIGNALHANDLER -#include -#ifndef QT_NO_QWS_MULTIPROCESS -# include -# include +#include "qlock_p.h" +#include "qwslock_p.h" -# include -#endif +#include #include QT_BEGIN_NAMESPACE @@ -87,39 +84,30 @@ 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); } 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 -#include +#include +#include #include 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 oldHandlers; + + QHash oldHandlers; #ifndef QT_NO_QWS_MULTIPROCESS - QVector semaphores; + QList locks; + QList wslocks; #endif QObjectCleanupHandler objects; -- cgit v0.12