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 #include "qstring.h" // inlined API
#if QT_CONFIG(thread)
# include "qthreadpool.h" // inlined API
#endif
#include "qurl.h" #include "qurl.h"
bool QUrl::operator<(const QUrl &url) const bool QUrl::operator<(const QUrl &url) const

View File

@ -258,7 +258,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable)
/*! /*!
\internal \internal
Helper function only to be called from waitForDone(int) Helper function only to be called from waitForDone()
Deletes all current threads. Deletes all current threads.
*/ */
@ -285,22 +285,17 @@ void QThreadPoolPrivate::reset()
/*! /*!
\internal \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) bool QThreadPoolPrivate::waitForDone(const QDeadlineTimer &timer)
{ {
QMutexLocker locker(&mutex);
while (!(queue.isEmpty() && activeThreads == 0) && !timer.hasExpired()) while (!(queue.isEmpty() && activeThreads == 0) && !timer.hasExpired())
noActiveThreads.wait(&mutex, timer); noActiveThreads.wait(&mutex, timer);
return queue.isEmpty() && activeThreads == 0; if (!queue.isEmpty() || activeThreads)
}
bool QThreadPoolPrivate::waitForDone(int msecs)
{
QMutexLocker locker(&mutex);
QDeadlineTimer timer(msecs);
if (!waitForDone(timer))
return false; return false;
reset(); reset();
// New jobs might have started during reset, but return anyway // New jobs might have started during reset, but return anyway
// as the active thread and task count did reach 0 once, and // 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 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; 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 otherwise it returns \c false. If \a msecs is -1, this function waits for
is ignored (waits for the last thread to exit). 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); Q_D(QThreadPool);
return d->waitForDone(msecs); return d->waitForDone(deadline);
} }
/*! /*!

View File

@ -72,7 +72,9 @@ public:
void reserveThread(); void reserveThread();
void releaseThread(); 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(); void clear();
@ -103,6 +105,13 @@ void QThreadPool::startOnReservedThread(Callable &&functionToRun)
startOnReservedThread(QRunnable::create(std::forward<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 QT_END_NAMESPACE
#endif #endif

View File

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