summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2011-01-13 13:52:17 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2011-01-14 15:06:41 (GMT)
commit324d08376ce6126a5675ffe35568920b76f01b5e (patch)
tree72edbb507788faca3ecdbe0d03d4973c446475b5 /src/corelib
parent2ebc2d6decb86d01672f0a5afb412f7aed53c49a (diff)
downloadQt-324d08376ce6126a5675ffe35568920b76f01b5e.zip
Qt-324d08376ce6126a5675ffe35568920b76f01b5e.tar.gz
Qt-324d08376ce6126a5675ffe35568920b76f01b5e.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 (cherry picked from commit 570e7b38487455d394b5b74a59edc639f3dc416f)
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);