summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2011-01-13 13:52:17 (GMT)
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2011-01-13 14:16:17 (GMT)
commit570e7b38487455d394b5b74a59edc639f3dc416f (patch)
tree5fff9159a5de8521ddcecc84bf5f1875714e44e9 /src/corelib
parent124ad6e903767fae510e0c2f0aba4029564a95c8 (diff)
downloadQt-570e7b38487455d394b5b74a59edc639f3dc416f.zip
Qt-570e7b38487455d394b5b74a59edc639f3dc416f.tar.gz
Qt-570e7b38487455d394b5b74a59edc639f3dc416f.tar.bz2
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
Diffstat (limited to 'src/corelib')
-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);