Android: fix timed QWaitCondition::wait() on Android >= 5.0.
wait() was always returning immediately, regardless of the timeout value, due to a timespec comparison from different clock types. On Android 5.0, qt_gettime() uses the monotonic clock but the wait condition was using the real time clock. __pthread_cond_timedwait_relative() is not exported anymore in Android 5.0, we therefore fall back to pthread_cond_timedwait(). Since the monotonic clock is now available, qt_gettime returns a time based on it. The wait condition consequently needs to use the monotonic clock. Change-Id: Ie7cf909b81107edd7207c3c039b3ec1f5422303f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
parent
8fccfef424
commit
921dd85c7a
@ -52,9 +52,12 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
// Android lacks pthread_condattr_setclock, but it does have a nice function
|
// pthread_condattr_setclock is available only since Android 5.0. On older versions, there's
|
||||||
// for relative waits. Use weakref so we can determine at runtime whether it is
|
// a private function for relative waits (hidden in 5.0).
|
||||||
// present.
|
// Use weakref so we can determine at runtime whether each of them is present.
|
||||||
|
static int local_condattr_setclock(pthread_condattr_t*, clockid_t)
|
||||||
|
__attribute__((weakref("pthread_condattr_setclock")));
|
||||||
|
|
||||||
static int local_cond_timedwait_relative(pthread_cond_t*, pthread_mutex_t *, const timespec *)
|
static int local_cond_timedwait_relative(pthread_cond_t*, pthread_mutex_t *, const timespec *)
|
||||||
__attribute__((weakref("__pthread_cond_timedwait_relative")));
|
__attribute__((weakref("__pthread_cond_timedwait_relative")));
|
||||||
#endif
|
#endif
|
||||||
@ -70,9 +73,14 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
|
|||||||
pthread_condattr_t condattr;
|
pthread_condattr_t condattr;
|
||||||
|
|
||||||
pthread_condattr_init(&condattr);
|
pthread_condattr_init(&condattr);
|
||||||
#if !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID) && (_POSIX_MONOTONIC_CLOCK-0 >= 0)
|
#if (_POSIX_MONOTONIC_CLOCK-0 >= 0)
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
if (local_condattr_setclock && QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock)
|
||||||
|
local_condattr_setclock(&condattr, CLOCK_MONOTONIC);
|
||||||
|
#elif !defined(Q_OS_MAC)
|
||||||
if (QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock)
|
if (QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock)
|
||||||
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
|
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
report_error(pthread_cond_init(cond, &condattr), where, "cv init");
|
report_error(pthread_cond_init(cond, &condattr), where, "cv init");
|
||||||
pthread_condattr_destroy(&condattr);
|
pthread_condattr_destroy(&condattr);
|
||||||
@ -108,7 +116,7 @@ public:
|
|||||||
{
|
{
|
||||||
timespec ti;
|
timespec ti;
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
if (Q_LIKELY(local_cond_timedwait_relative)) {
|
if (local_cond_timedwait_relative) {
|
||||||
ti.tv_sec = time / 1000;
|
ti.tv_sec = time / 1000;
|
||||||
ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000;
|
ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000;
|
||||||
return local_cond_timedwait_relative(&cond, &mutex, &ti);
|
return local_cond_timedwait_relative(&cond, &mutex, &ti);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user