From fb01907050f7fac4a898c87652fc2be5b7049477 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 9 Nov 2011 16:19:11 +0100 Subject: [PATCH] Correctly normalize timevals before calling select() When normalizing timevals, we need to bound the tv_usec member to 0-999999 inclusive, otherwise select() may return EINVAL. When rounding timevals to the nearest millisecond in the UNIX event dispatcher, pass the timeval through normalizeTimeval() when returning. As discovered on Mac OS X with tst_QFutureWatcher, starting a 10 second timer would end up calling select() with timeval = { 9l, 1000000 }, resulting in numerous "select: Invalid argument" warnings being printed to the console. Change-Id: Ic539e935bf847e0d4c22a73ad203e3a7a81d0690 Reviewed-by: Olivier Goffart --- src/corelib/kernel/qcore_unix_p.h | 8 ++++---- src/corelib/kernel/qeventdispatcher_unix.cpp | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 00ec4af203..e7259d29c9 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -101,13 +101,13 @@ QT_BEGIN_NAMESPACE // Internal operator functions for timevals inline timeval &normalizedTimeval(timeval &t) { - while (t.tv_usec > 1000000l) { + while (t.tv_usec >= 1000000) { ++t.tv_sec; - t.tv_usec -= 1000000l; + t.tv_usec -= 1000000; } - while (t.tv_usec < 0l) { + while (t.tv_usec < 0) { --t.tv_sec; - t.tv_usec += 1000000l; + t.tv_usec += 1000000; } return t; } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 3c7a48ac68..27efac6985 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -448,11 +448,7 @@ static timeval roundToMillisecond(timeval val) int us = val.tv_usec % 1000; val.tv_usec += 1000 - us; - if (val.tv_usec > 1000000) { - val.tv_usec -= 1000000; - ++val.tv_sec; - } - return val; + return normalizedTimeval(val); } /*