diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2011-01-13 13:52:17 (GMT) |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2011-01-13 14:16:17 (GMT) |
commit | 570e7b38487455d394b5b74a59edc639f3dc416f (patch) | |
tree | 5fff9159a5de8521ddcecc84bf5f1875714e44e9 /src/corelib | |
parent | 124ad6e903767fae510e0c2f0aba4029564a95c8 (diff) | |
download | Qt-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.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); |