summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qsystemsemaphore_symbian.cpp20
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);