{
return p.second < priority;
}
+
inline bool operator<(const QPair<QRunnable *, int> &p, int priority)
{
return priority < p.second;
/*
QThreadPool private class.
*/
-
-
-/*!\internal
-
-*/
QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager)
- :manager(manager), runnable(nullptr)
-{ }
-
-/* \internal
+ : manager(manager),
+ runnable(nullptr)
+{
+}
-*/
void QThreadPoolThread::run()
{
QMutexLocker locker(&manager->mutex);
if (r) {
const bool autoDelete = r->autoDelete();
-
// run the task
locker.unlock();
QT_TRY {
}
locker.relock();
- if (autoDelete && !--r->ref)
+ if (autoDelete && !--r->ref) {
delete r;
+ }
}
// if too many threads are active, expire this thread
- if (manager->tooManyThreadsActive())
+ if (manager->tooManyThreadsActive()) {
break;
+ }
r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : nullptr;
} while (r != nullptr);
// wait for work, exiting after the expiry timeout is reached
runnableReady.wait(locker.mutex(), manager->expiryTimeout);
++manager->activeThreads;
- if (manager->waitingThreads.removeOne(this))
+ if (manager->waitingThreads.removeOne(this)) {
expired = true;
+ }
}
if (expired) {
manager->expiredThreads.enqueue(this);
void QThreadPoolThread::registerThreadInactive()
{
- if (--manager->activeThreads == 0)
+ if (--manager->activeThreads == 0) {
manager->noActiveThreads.wakeAll();
+ }
}
*/
QThreadPoolPrivate:: QThreadPoolPrivate()
: isExiting(false),
- expiryTimeout(30000),
- maxThreadCount(qAbs(QThread::idealThreadCount())),
- reservedThreads(0),
- activeThreads(0)
-{ }
+ expiryTimeout(30000),
+ maxThreadCount(qAbs(QThread::idealThreadCount())),
+ reservedThreads(0),
+ activeThreads(0)
+{
+}
bool QThreadPoolPrivate::tryStart(QRunnable *task)
{
}
// can't do anything if we're over the limit
- if (activeThreadCount() >= maxThreadCount)
+ if (activeThreadCount() >= maxThreadCount) {
return false;
+ }
if (waitingThreads.count() > 0) {
// recycle an available thread
void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
{
- if (runnable->autoDelete())
+ if (runnable->autoDelete()) {
++runnable->ref;
+ }
// put it on the queue
- QList<QPair<QRunnable *, int> >::iterator at =
- qUpperBound(queue.begin(), queue.end(), priority);
+ QList<QPair<QRunnable *, int> >::iterator at = qUpperBound(queue.begin(), queue.end(), priority);
queue.insert(at, qMakePair(runnable, priority));
}
int QThreadPoolPrivate::activeThreadCount() const
{
- return (allThreads.count()
- - expiredThreads.count()
- - waitingThreads.count()
- + reservedThreads);
+ return (allThreads.count() - expiredThreads.count() - waitingThreads.count() + reservedThreads);
}
void QThreadPoolPrivate::tryToStartMoreThreads()
{
// try to push tasks on the queue to any available threads
- while (!queue.isEmpty() && tryStart(queue.first().first))
+ while (!queue.isEmpty() && tryStart(queue.first().first)) {
queue.removeFirst();
+ }
}
bool QThreadPoolPrivate::tooManyThreadsActive() const
return activeThreadCount > maxThreadCount && (activeThreadCount - reservedThreads) > 1;
}
-/*! \internal
-
+/*!
+ \internal
*/
void QThreadPoolPrivate::startThread(QRunnable *runnable)
{
allThreads.insert(thread.data());
++activeThreads;
- if (runnable->autoDelete())
+ if (runnable->autoDelete()) {
++runnable->ref;
+ }
thread->runnable = runnable;
thread.take()->start();
}
{
QMutexLocker locker(&mutex);
if (msecs < 0) {
- if (!queue.isEmpty() || activeThreads != 0)
+ if (!queue.isEmpty() || activeThreads != 0) {
noActiveThreads.wait(locker.mutex());
+ }
} else {
- if (!queue.isEmpty() || activeThreads != 0)
+ if (!queue.isEmpty() || activeThreads != 0) {
noActiveThreads.wait(locker.mutex(), msecs);
+ }
}
- return queue.isEmpty() && activeThreads == 0;
+ return (queue.isEmpty() && activeThreads == 0);
}
/*!
*/
QThreadPool::QThreadPool(QObject *parent)
: QObject(*new QThreadPoolPrivate, parent)
-{ }
+{
+}
/*!
Destroys the QThreadPool.
*/
void QThreadPool::start(QRunnable *runnable, int priority)
{
- if (!runnable)
+ if (!runnable) {
return;
+ }
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
if (!d->tryStart(runnable)) {
d->enqueueTask(runnable, priority);
- if (!d->waitingThreads.isEmpty())
+ if (!d->waitingThreads.isEmpty()) {
d->waitingThreads.takeFirst()->runnableReady.wakeOne();
+ }
}
}
*/
bool QThreadPool::tryStart(QRunnable *runnable)
{
- if (!runnable)
+ if (!runnable) {
return false;
+ }
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
- if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount)
+ if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount) {
return false;
+ }
return d->tryStart(runnable);
}
-/*! \property QThreadPool::expiryTimeout
+/*!
+ \property QThreadPool::expiryTimeout
Threads that are unused for \a expiryTimeout milliseconds are considered
to have expired and will exit. Such threads will be restarted as needed.
We recommend setting the \a expiryTimeout immediately after creating the
thread pool, but before calling start().
*/
-
int QThreadPool::expiryTimeout() const
{
Q_D(const QThreadPool);
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
- if (d->expiryTimeout == expiryTimeout)
+ if (d->expiryTimeout == expiryTimeout) {
return;
+ }
d->expiryTimeout = expiryTimeout;
}
-/*! \property QThreadPool::maxThreadCount
+/*!
+ \property QThreadPool::maxThreadCount
This property represents the maximum number of threads used by the thread
pool.
The default \a maxThreadCount is QThread::idealThreadCount().
*/
-
int QThreadPool::maxThreadCount() const
{
Q_D(const QThreadPool);
d->tryToStartMoreThreads();
}
-/*! \property QThreadPool::activeThreadCount
+/*!
+ \property QThreadPool::activeThreadCount
This property represents the number of active threads in the thread pool.
\sa reserveThread(), releaseThread()
*/
-
int QThreadPool::activeThreadCount() const
{
Q_D(const QThreadPool);
activeThreadCount() to return a value greater than maxThreadCount() .
\sa releaseThread()
- */
+*/
void QThreadPool::reserveThread()
{
Q_D(QThreadPool);
{
Q_D(QThreadPool);
bool rc = d->waitForDone(msecs);
- if (rc)
- d->reset();
+ if (rc) {
+ d->reset();
+ }
return rc;
}