From f2cf5f5417d4df68eb0677e375cb81e39286c05f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 8 Nov 2019 21:16:55 +0100 Subject: [PATCH] Port QThread::wait() to QDeadlineTimer So we are in sync with QWaitCondition::wait(). Task-number: QTBUG-64266 Change-Id: I1d7487786513241cedd35d202c4ddee4937b08ec Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread.cpp | 30 ++++++++++++++----- src/corelib/thread/qthread.h | 8 ++--- src/corelib/thread/qthread_unix.cpp | 4 +-- src/corelib/thread/qthread_win.cpp | 6 ++-- src/network/access/qnetworkaccessmanager.cpp | 2 +- src/network/access/qnetworkreplyhttpimpl.cpp | 2 +- .../bearer/qnetworkconfigmanager_p.cpp | 2 +- 7 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 880ae9e0469..791b7658808 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -49,6 +49,8 @@ #include "qthread_p.h" #include "private/qcoreapplication_p.h" +#include + QT_BEGIN_NAMESPACE /* @@ -726,7 +728,8 @@ QThread::Priority QThread::priority() const */ /*! - \fn bool QThread::wait(unsigned long time) + \fn bool QThread::wait(QDeadlineTimer deadline) + \since 5.15 Blocks the thread until either of these conditions is met: @@ -735,12 +738,14 @@ QThread::Priority QThread::priority() const execution (i.e. when it returns from \l{run()}). This function will return true if the thread has finished. It also returns true if the thread has not been started yet. - \li \a time milliseconds has elapsed. If \a time is ULONG_MAX (the - default), then the wait will never timeout (the thread must - return from \l{run()}). This function will return false if the - wait timed out. + \li The \a deadline is reached. This function will return false if the + deadline is reached. \endlist + A deadline timer set to \c QDeadlineTimer::Forever (the default) will never + time out: in this case, the function only returns when the thread returns + from \l{run()} or if the thread has not yet started. + This provides similar functionality to the POSIX \c pthread_join() function. @@ -833,9 +838,9 @@ void QThread::exit(int returnCode) } } -bool QThread::wait(unsigned long time) +bool QThread::wait(QDeadlineTimer deadline) { - Q_UNUSED(time); + Q_UNUSED(deadline); return false; } @@ -966,6 +971,17 @@ void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) } } +/*! + \fn bool QThread::wait(unsigned long time) + \overload +*/ +bool QThread::wait(unsigned long time) +{ + if (time == std::numeric_limits::max()) + return wait(QDeadlineTimer(QDeadlineTimer::Forever)); + return wait(QDeadlineTimer(time)); +} + #if QT_CONFIG(thread) /*! diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index c7a6dc8f1a0..2072e223404 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -42,6 +42,7 @@ #define QTHREAD_H #include +#include // For QThread::create. The configure-time test just checks for the availability // of std::future and std::async; for the C++17 codepath we perform some extra @@ -57,8 +58,6 @@ # endif #endif -#include - QT_BEGIN_NAMESPACE @@ -135,8 +134,9 @@ public Q_SLOTS: void quit(); public: - // default argument causes thread to block indefinetely - bool wait(unsigned long time = ULONG_MAX); + bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever)); + // ### Qt6 inline this function + bool wait(unsigned long time); static void sleep(unsigned long); static void msleep(unsigned long); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index b19922753a6..62f01798028 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -751,7 +751,7 @@ void QThread::terminate() #endif } -bool QThread::wait(unsigned long time) +bool QThread::wait(QDeadlineTimer deadline) { Q_D(QThread); QMutexLocker locker(&d->mutex); @@ -765,7 +765,7 @@ bool QThread::wait(unsigned long time) return true; while (d->running) { - if (!d->thread_done.wait(locker.mutex(), QDeadlineTimer(time))) + if (!d->thread_done.wait(locker.mutex(), deadline)) return false; } return true; diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index a72df2fc404..3df7080caf9 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -610,7 +610,7 @@ void QThread::terminate() QThreadPrivate::finish(this, false); } -bool QThread::wait(unsigned long time) +bool QThread::wait(QDeadlineTimer deadline) { Q_D(QThread); QMutexLocker locker(&d->mutex); @@ -627,9 +627,9 @@ bool QThread::wait(unsigned long time) bool ret = false; #ifndef Q_OS_WINRT - switch (WaitForSingleObject(d->handle, time)) { + switch (WaitForSingleObject(d->handle, deadline.remainingTime())) { #else - switch (WaitForSingleObjectEx(d->handle, time, false)) { + switch (WaitForSingleObjectEx(d->handle, deadline.remainingTime(), false)) { #endif case WAIT_OBJECT_0: ret = true; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 3e1e6d8be82..6c1cb420fe8 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1981,7 +1981,7 @@ void QNetworkAccessManagerPrivate::destroyThread() { if (thread) { thread->quit(); - thread->wait(5000); + thread->wait(QDeadlineTimer(5000)); if (thread->isFinished()) delete thread; else diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index a13c2b144c3..ba9d0a76d5e 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -986,7 +986,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq } thread->quit(); - thread->wait(5000); + thread->wait(QDeadlineTimer(5000)); if (thread->isFinished()) delete thread; else diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index b4324446699..252b88d36a1 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -93,7 +93,7 @@ void QNetworkConfigurationManagerPrivate::cleanup() { QThread* thread = bearerThread; deleteLater(); - if (thread->wait(5000)) + if (thread->wait(QDeadlineTimer(5000))) delete thread; }