QThreadPool: obey the docs that say we always use at least 1 thread
Even if the user (usually accidentally) sets a thread count of zero or negative. The reporter in the bug report did QThread::idealThreadCount() - 1 on a 1 CPU system... Drive-by add to the documentation and the missing #include. Fixes: QTBUG-93007 Change-Id: I6cdea00671e8479b9c50fffd167807d14e030154 Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> (cherry picked from commit 885eff053797d56f2e295558d0a71b030fbb1a69) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
25d9bf39d9
commit
c0d310d996
@ -176,7 +176,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// can't do anything if we're over the limit
|
// can't do anything if we're over the limit
|
||||||
if (activeThreadCount() >= maxThreadCount)
|
if (activeThreadCount() >= maxThreadCount())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (waitingThreads.count() > 0) {
|
if (waitingThreads.count() > 0) {
|
||||||
@ -249,7 +249,7 @@ void QThreadPoolPrivate::tryToStartMoreThreads()
|
|||||||
bool QThreadPoolPrivate::tooManyThreadsActive() const
|
bool QThreadPoolPrivate::tooManyThreadsActive() const
|
||||||
{
|
{
|
||||||
const int activeThreadCount = this->activeThreadCount();
|
const int activeThreadCount = this->activeThreadCount();
|
||||||
return activeThreadCount > maxThreadCount && (activeThreadCount - reservedThreads) > 1;
|
return activeThreadCount > maxThreadCount() && (activeThreadCount - reservedThreads) > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -571,7 +571,7 @@ bool QThreadPool::tryStart(std::function<void()> functionToRun)
|
|||||||
|
|
||||||
Q_D(QThreadPool);
|
Q_D(QThreadPool);
|
||||||
QMutexLocker locker(&d->mutex);
|
QMutexLocker locker(&d->mutex);
|
||||||
if (!d->allThreads.isEmpty() && d->activeThreadCount() >= d->maxThreadCount)
|
if (!d->allThreads.isEmpty() && d->activeThreadCount() >= d->maxThreadCount())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QRunnable *runnable = QRunnable::create(std::move(functionToRun));
|
QRunnable *runnable = QRunnable::create(std::move(functionToRun));
|
||||||
@ -612,7 +612,9 @@ void QThreadPool::setExpiryTimeout(int expiryTimeout)
|
|||||||
|
|
||||||
/*! \property QThreadPool::maxThreadCount
|
/*! \property QThreadPool::maxThreadCount
|
||||||
|
|
||||||
\brief the maximum number of threads used by the thread pool.
|
\brief the maximum number of threads used by the thread pool. This property
|
||||||
|
will default to the value of QThread::idealThreadCount() at the moment the
|
||||||
|
QThreadPool object is created.
|
||||||
|
|
||||||
\note The thread pool will always use at least 1 thread, even if
|
\note The thread pool will always use at least 1 thread, even if
|
||||||
\a maxThreadCount limit is zero or negative.
|
\a maxThreadCount limit is zero or negative.
|
||||||
@ -623,7 +625,7 @@ void QThreadPool::setExpiryTimeout(int expiryTimeout)
|
|||||||
int QThreadPool::maxThreadCount() const
|
int QThreadPool::maxThreadCount() const
|
||||||
{
|
{
|
||||||
Q_D(const QThreadPool);
|
Q_D(const QThreadPool);
|
||||||
return d->maxThreadCount;
|
return d->requestedMaxThreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QThreadPool::setMaxThreadCount(int maxThreadCount)
|
void QThreadPool::setMaxThreadCount(int maxThreadCount)
|
||||||
@ -631,10 +633,10 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount)
|
|||||||
Q_D(QThreadPool);
|
Q_D(QThreadPool);
|
||||||
QMutexLocker locker(&d->mutex);
|
QMutexLocker locker(&d->mutex);
|
||||||
|
|
||||||
if (maxThreadCount == d->maxThreadCount)
|
if (maxThreadCount == d->requestedMaxThreadCount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->maxThreadCount = maxThreadCount;
|
d->requestedMaxThreadCount = maxThreadCount;
|
||||||
d->tryToStartMoreThreads();
|
d->tryToStartMoreThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "QtCore/qmutex.h"
|
#include "QtCore/qmutex.h"
|
||||||
#include "QtCore/qthread.h"
|
#include "QtCore/qthread.h"
|
||||||
#include "QtCore/qwaitcondition.h"
|
#include "QtCore/qwaitcondition.h"
|
||||||
|
#include "QtCore/qthreadpool.h"
|
||||||
#include "QtCore/qset.h"
|
#include "QtCore/qset.h"
|
||||||
#include "QtCore/qqueue.h"
|
#include "QtCore/qqueue.h"
|
||||||
#include "private/qobject_p.h"
|
#include "private/qobject_p.h"
|
||||||
@ -158,6 +159,8 @@ public:
|
|||||||
void tryToStartMoreThreads();
|
void tryToStartMoreThreads();
|
||||||
bool tooManyThreadsActive() const;
|
bool tooManyThreadsActive() const;
|
||||||
|
|
||||||
|
int maxThreadCount() const
|
||||||
|
{ 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(int msecs);
|
||||||
@ -174,7 +177,7 @@ public:
|
|||||||
QWaitCondition noActiveThreads;
|
QWaitCondition noActiveThreads;
|
||||||
|
|
||||||
int expiryTimeout = 30000;
|
int expiryTimeout = 30000;
|
||||||
int maxThreadCount = QThread::idealThreadCount();
|
int requestedMaxThreadCount = QThread::idealThreadCount(); // don't use this directly
|
||||||
int reservedThreads = 0;
|
int reservedThreads = 0;
|
||||||
int activeThreads = 0;
|
int activeThreads = 0;
|
||||||
uint stackSize = 0;
|
uint stackSize = 0;
|
||||||
|
@ -483,7 +483,7 @@ void tst_QThreadPool::setMaxThreadCountStartsAndStopsThreads()
|
|||||||
};
|
};
|
||||||
|
|
||||||
QThreadPool threadPool;
|
QThreadPool threadPool;
|
||||||
threadPool.setMaxThreadCount(1);
|
threadPool.setMaxThreadCount(-1); // docs say we'll always start at least one
|
||||||
|
|
||||||
WaitingTask *task = new WaitingTask;
|
WaitingTask *task = new WaitingTask;
|
||||||
threadPool.start(task);
|
threadPool.start(task);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user