Fix the timeout calculation for futexes in QMutex.
Recalculate how much time is remaining. This commit needs to be backported to 4.8. Change-Id: Ib587335bb90306e65969bb26256fb388f8f6bd24 Merge-request: 20 Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com> Reviewed-on: http://codereview.qt.nokia.com/1666 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
This commit is contained in:
parent
2c8e030a3f
commit
412ef92162
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user