summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qmutex_unix.cpp
diff options
context:
space:
mode:
authorWater-Team <water@pad.test.qt.nokia.com>2011-07-15 23:00:15 (GMT)
committerWater-Team <water@pad.test.qt.nokia.com>2011-07-15 23:00:15 (GMT)
commit66ff42cade328208774c29d2aea086f4b79c3b6c (patch)
treebdcfb656e602ec09cc931dd239fbefb9df28a49b /src/corelib/thread/qmutex_unix.cpp
parent2a326fdc8f8bf2bd2c5764394616100906d9db2d (diff)
parentc0b8b0f58bad6c238398055ef4c8aa8d45d1306d (diff)
downloadQt-66ff42cade328208774c29d2aea086f4b79c3b6c.zip
Qt-66ff42cade328208774c29d2aea086f4b79c3b6c.tar.gz
Qt-66ff42cade328208774c29d2aea086f4b79c3b6c.tar.bz2
Merge branch '4.8-upstream' into master-water
Diffstat (limited to 'src/corelib/thread/qmutex_unix.cpp')
-rw-r--r--src/corelib/thread/qmutex_unix.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 12bc795..e692e19 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -60,6 +60,7 @@
# include <linux/futex.h>
# include <sys/syscall.h>
# include <unistd.h>
+# include <QtCore/qelapsedtimer.h>
#endif
QT_BEGIN_NAMESPACE
@@ -138,16 +139,31 @@ static inline int _q_futex(volatile int *addr, int op, int val, const struct tim
bool QMutexPrivate::wait(int timeout)
{
+ struct timespec ts, *pts = 0;
+ QElapsedTimer timer;
+ if (timeout >= 0) {
+ ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
+ ts.tv_sec = (timeout / 1000);
+ pts = &ts;
+ timer.start();
+ }
while (contenders.fetchAndStoreAcquire(2) > 0) {
- struct timespec ts, *pts = 0;
- if (timeout >= 0) {
- ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
- ts.tv_sec = (timeout / 1000);
- pts = &ts;
- }
int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0);
if (r != 0 && errno == ETIMEDOUT)
return false;
+
+ if (pts) {
+ // recalculate the timeout
+ qint64 xtimeout = timeout * 1000 * 1000;
+ xtimeout -= timer.nsecsElapsed();
+ if (xtimeout < 0) {
+ // timer expired after we returned
+ return false;
+ }
+
+ ts.tv_sec = timeout / Q_INT64_C(1000) / 1000 / 1000;
+ ts.tv_nsec = timeout % (Q_INT64_C(1000) * 1000 * 1000);
+ }
}
return true;
}