From 570e7b38487455d394b5b74a59edc639f3dc416f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 13 Jan 2011 15:52:17 +0200 Subject: Fix QSystemSemaphore handle management issues in Symbian QSystemSemaphore native RSemaphore handle was unnecessarily created again on each acquire. The creation logic was also susceptible for random failures when two or more threads tried simultaneously acquire the semaphore. Task-number: QTBUG-16615 Reviewed-by: Janne Koskinen --- src/corelib/kernel/qsystemsemaphore_symbian.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp index a25a119..07cfffc 100644 --- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp +++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp @@ -73,6 +73,9 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function, int err) case KErrInUse: errorString = QCoreApplication::tr("%1: out of resources", "QSystemSemaphore").arg(function); error = QSystemSemaphore::OutOfResources; + case KErrPermissionDenied: + errorString = QCoreApplication::tr("%1: permission denied", "QSystemSemaphore").arg(function); + error = QSystemSemaphore::PermissionDenied; break; default: errorString = QCoreApplication::tr("%1: unknown error %2", "QSystemSemaphore").arg(function).arg(err); @@ -86,15 +89,24 @@ default: int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) { + if (semaphore.Handle()) { + return semaphore.Handle(); + } + // don't allow making handles on empty keys if (key.isEmpty()) return 0; + QString safeName = makeKeyFileName(); TPtrC name(qt_QString2TPtrC(safeName)); - int err; - err = semaphore.OpenGlobal(name,EOwnerProcess); - if (err == KErrNotFound){ - err = semaphore.CreateGlobal(name,initialValue, EOwnerProcess); + int err = KErrAlreadyExists; + int tryCount = 10; + // Sort out race conditions by retrying several times until existing handle is acquired. + // Sometimes opening can fail inexplicably with KErrPermissionDenied many times in a row. + while (err != KErrNoMemory && err != KErrNone && tryCount-- >= 0) { + err = semaphore.CreateGlobal(name, initialValue, EOwnerProcess); + if (err != KErrNoMemory && err != KErrNone) + err = semaphore.OpenGlobal(name,EOwnerProcess); } if (err){ setErrorString(QLatin1String("QSystemSemaphore::handle"),err); -- cgit v0.12 From c67b4cda2f5a7afd401ec3106e3a7b018fd9881d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 13 Jan 2011 16:08:42 +0200 Subject: Fix QSharedMemory and QSystemSemaphore autotests for Symbian Reviewed-by: Janne Koskinen --- tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp | 10 +++++----- tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp index 5825524..50205bc 100644 --- a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp @@ -51,7 +51,7 @@ #define EXISTING_SIZE 1024 #ifdef Q_OS_SYMBIAN -#define SRCDIR "c:/data/qsharedmemorytemp/" +#define SRCDIR "c:/data/qsharedmemorytemp/lackey/" #define LACKEYDIR SRCDIR "lackey" #elif defined(Q_OS_WINCE) #define LACKEYDIR SRCDIR @@ -624,6 +624,10 @@ public: QVERIFY(producer.isAttached()); char *memory = (char*)producer.data(); memory[1] = '0'; +#if defined(Q_OS_SYMBIAN) + // Sleep a while to ensure that consumers start properly + QTest::qSleep(1000); +#endif QTime timer; timer.start(); int i = 0; @@ -645,10 +649,6 @@ public: memory[0] = 'E'; QVERIFY(producer.unlock()); -#if defined(Q_OS_SYMBIAN) - // Sleep a while to ensure that consumers start properly - QTest::qSleep(1000); -#endif } private: diff --git a/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro b/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro index 8a5f8b2..e21e5df 100644 --- a/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro +++ b/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro @@ -1,4 +1,4 @@ -CONFIG += qttest_p4 +load(qttest_p4) #QT = core include(../qsharedmemory/src/src.pri) @@ -31,5 +31,8 @@ QT += script lackey.sources = ../lackey/lackey.exe lackey.path = /sys/bin DEPLOYMENT += lackey + +# PowerMgmt capability needed to kill lackey process +TARGET.CAPABILITY = PowerMgmt } -- cgit v0.12