QThreadPool: add waitForDone() based on QDeadlineTimer

It was already being used internally this way, so all we needed was to
provide the front-end API and inline the old API.

[ChangeLog][QtCore][QThreadPool] Added an overload of waitForDone()
based on QDeadlineTimer.

Fixes: QTBUG-125107
Change-Id: Ic5b1273bb0204c31afd8fffd17ccf7c5bee07c35
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
Thiago Macieira 2024-05-06 10:53:06 -07:00
parent 95d4e6baba
commit 179e79b18d
4 changed files with 32 additions and 16 deletions

View File

@ -1078,6 +1078,10 @@ bool QRegularExpression::operator==(const QRegularExpression &other) const
#include "qstring.h" // inlined API
#if QT_CONFIG(thread)
# include "qthreadpool.h" // inlined API
#endif
#include "qurl.h"
bool QUrl::operator<(const QUrl &url) const

View File

@ -258,7 +258,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable)
/*!
\internal
Helper function only to be called from waitForDone(int)
Helper function only to be called from waitForDone()
Deletes all current threads.
*/
@ -285,22 +285,17 @@ void QThreadPoolPrivate::reset()
/*!
\internal
Helper function only to be called from waitForDone(int)
Helper function only to be called from the public waitForDone()
*/
bool QThreadPoolPrivate::waitForDone(const QDeadlineTimer &timer)
{
QMutexLocker locker(&mutex);
while (!(queue.isEmpty() && activeThreads == 0) && !timer.hasExpired())
noActiveThreads.wait(&mutex, timer);
return queue.isEmpty() && activeThreads == 0;
}
bool QThreadPoolPrivate::waitForDone(int msecs)
{
QMutexLocker locker(&mutex);
QDeadlineTimer timer(msecs);
if (!waitForDone(timer))
if (!queue.isEmpty() || activeThreads)
return false;
reset();
// New jobs might have started during reset, but return anyway
// as the active thread and task count did reach 0 once, and
@ -808,15 +803,24 @@ void QThreadPool::startOnReservedThread(QRunnable *runnable)
*/
/*!
\fn bool QThreadPool::waitForDone(int msecs)
Waits up to \a msecs milliseconds for all threads to exit and removes all
threads from the thread pool. Returns \c true if all threads were removed;
otherwise it returns \c false. If \a msecs is -1 (the default), the timeout
is ignored (waits for the last thread to exit).
otherwise it returns \c false. If \a msecs is -1, this function waits for
the last thread to exit.
*/
bool QThreadPool::waitForDone(int msecs)
/*!
\since 6.8
Waits until \a deadline expires for all threads to exit and removes all
threads from the thread pool. Returns \c true if all threads were removed;
otherwise it returns \c false.
*/
bool QThreadPool::waitForDone(QDeadlineTimer deadline)
{
Q_D(QThreadPool);
return d->waitForDone(msecs);
return d->waitForDone(deadline);
}
/*!

View File

@ -72,7 +72,9 @@ public:
void reserveThread();
void releaseThread();
bool waitForDone(int msecs = -1);
QT_CORE_INLINE_SINCE(6, 8)
bool waitForDone(int msecs);
bool waitForDone(QDeadlineTimer deadline = QDeadlineTimer::Forever);
void clear();
@ -103,6 +105,13 @@ void QThreadPool::startOnReservedThread(Callable &&functionToRun)
startOnReservedThread(QRunnable::create(std::forward<Callable>(functionToRun)));
}
#if QT_CORE_INLINE_IMPL_SINCE(6, 8)
bool QThreadPool::waitForDone(int msecs)
{
return waitForDone(QDeadlineTimer(msecs));
}
#endif
QT_END_NAMESPACE
#endif

View File

@ -128,7 +128,6 @@ public:
{ return qMax(requestedMaxThreadCount, 1); } // documentation says we start at least one
void startThread(QRunnable *runnable = nullptr);
void reset();
bool waitForDone(int msecs);
bool waitForDone(const QDeadlineTimer &timer);
void clear();
void stealAndRunRunnable(QRunnable *runnable);