diff options
-rw-r--r-- | src/corelib/kernel/qsystemsemaphore_symbian.cpp | 20 |
1 files 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); |