summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2011-05-05 15:03:54 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2011-05-05 15:03:54 (GMT)
commitb54af0a9d6406356616889826e31925d2fa05718 (patch)
tree9027a4d6f082c8b9c0a2cd7a8922d6de8258d3a8 /src/corelib/thread
parentd1ac6af4f30e822e161fd8772104aa2e30e55a2f (diff)
downloadQt-b54af0a9d6406356616889826e31925d2fa05718.zip
Qt-b54af0a9d6406356616889826e31925d2fa05718.tar.gz
Qt-b54af0a9d6406356616889826e31925d2fa05718.tar.bz2
Do not allow multiple threads to acquire a QMutex
After the mutex optimizations on Mac, we did not handle the case where semaphore_wait() could return KERN_ABORTED. Under heavy contention, this happens, and when running in release mode, the assert in qmutex.cpp is not executed. The code silently allows multiple threads to continue as if it had acquired the mutex exclusively. Fix this by checking for KERN_ABORTED from semaphore_wait(), and retry the wait. We do not handle KERN_ABORTED for timed waits, simply return false and let the code doing the tryLock() handle it how it deems best. Reviewed-by: joao
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qmutex_unix.cpp13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 11e2060..b584ae5 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -107,18 +107,21 @@ bool QMutexPrivate::wait(int timeout)
// lock acquired without waiting
return true;
}
- bool returnValue;
+ kern_return_t r;
if (timeout < 0) {
- returnValue = semaphore_wait(mach_semaphore) == KERN_SUCCESS;
+ do {
+ r = semaphore_wait(mach_semaphore);
+ } while (r == KERN_ABORTED);
+ if (r != KERN_SUCCESS)
+ qWarning("QMutex: infinite wait failed, error %d", r);
} else {
mach_timespec_t ts;
ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
ts.tv_sec = (timeout / 1000);
- kern_return_t r = semaphore_timedwait(mach_semaphore, ts);
- returnValue = r == KERN_SUCCESS;
+ r = semaphore_timedwait(mach_semaphore, ts);
}
contenders.deref();
- return returnValue;
+ return r == KERN_SUCCESS;
}
void QMutexPrivate::wakeUp()