From bc00daae71df8a9691403b43e454aed4868ff9f3 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Tue, 23 Feb 2021 13:02:26 +0100 Subject: [PATCH] Add support to set thread priority to QThreadPool Currently, QThreadPool's generated threads inherit the priority from the thread they are created and that cannot be changed. This merge request adds a property to QThreadPool so that the priority of the threads can be different. The default behavior does not change. [ChangeLog][QtCore][QThreadPool] QThreadPool can now be configured to use a different thread priority when creating new threads than the one it inherits from the thread it was created in. This will only apply to the threads started after the property is changed. Fixes: QTBUG-3481 Change-Id: Ic98d4312d055a3357771abb656516ebd0715918d Reviewed-by: Thiago Macieira --- src/corelib/thread/qthreadpool.cpp | 30 +++++++++++++++++-- src/corelib/thread/qthreadpool.h | 4 +++ src/corelib/thread/qthreadpool_p.h | 1 + .../thread/qthreadpool/tst_qthreadpool.cpp | 20 +++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 6d258af9df..911bf8a53a 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -194,7 +194,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task) ++activeThreads; thread->runnable = task; - thread->start(); + thread->start(threadPriority); return true; } @@ -265,7 +265,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) ++activeThreads; thread->runnable = runnable; - thread.take()->start(); + thread.take()->start(threadPriority); } /*! @@ -698,6 +698,32 @@ uint QThreadPool::stackSize() const return d->stackSize; } +/*! \property QThreadPool::threadPriority + \brief the thread priority for new worker threads. + + The value of the property is only used when the thread pool starts + new threads. Changing it has no effect for already running threads. + + The default value is QThread::InheritPriority, which makes QThread + use the same priority as the one the QThreadPool object lives in. + + \sa QThread::ThreadPriority + + \since 6.2 +*/ + +void QThreadPool::setThreadPriority(QThread::Priority priority) +{ + Q_D(QThreadPool); + d->threadPriority = priority; +} + +QThread::Priority QThreadPool::threadPriority() const +{ + Q_D(const QThreadPool); + return d->threadPriority; +} + /*! Releases a thread previously reserved by a call to reserveThread(). diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index a559eff49a..f3d7e2254b 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -60,6 +60,7 @@ class Q_CORE_EXPORT QThreadPool : public QObject Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount) Q_PROPERTY(int activeThreadCount READ activeThreadCount) Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize) + Q_PROPERTY(QThread::Priority threadPriority READ threadPriority WRITE setThreadPriority) friend class QFutureInterfaceBase; public: @@ -85,6 +86,9 @@ public: void setStackSize(uint stackSize); uint stackSize() const; + void setThreadPriority(QThread::Priority priority); + QThread::Priority threadPriority() const; + void reserveThread(); void releaseThread(); diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 4d73a480b5..1f8a22dcdf 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -178,6 +178,7 @@ public: int reservedThreads = 0; int activeThreads = 0; uint stackSize = 0; + QThread::Priority threadPriority = QThread::InheritPriority; }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 3c50c6315b..0fb4bfbe56 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -75,6 +75,7 @@ private slots: void singleton(); void destruction(); void threadRecycling(); + void threadPriority(); void expiryTimeout(); void expiryTimeoutRace(); #ifndef QT_NO_EXCEPTIONS @@ -323,6 +324,25 @@ void tst_QThreadPool::threadRecycling() QCOMPARE(thread2, thread3); } +/* + Test that the thread priority from the thread created by the pool matches + the one configured on the pool. +*/ +void tst_QThreadPool::threadPriority() +{ + QThread::Priority priority = QThread::HighPriority; + QThreadPool threadPool; + threadPool.setThreadPriority(priority); + + threadPool.start(new ThreadRecorderTask()); + threadRecyclingSemaphore.acquire(); + QThread *thread = recycledThread; + + QTest::qSleep(100); + + QCOMPARE(thread->priority(), priority); +} + class ExpiryTimeoutTask : public QRunnable { public: