summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2013-06-21 10:32:17 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-24 13:09:46 +0200
commitdacf9961da86751a59da0e84bc943fe0d1c8d95b (patch)
tree88fb959024904484ec8e7442b88c4777246a42a4 /src/corelib/thread
parent7c2a418857cd20e3e59852f0c1561a26f17d9825 (diff)
QThreadPool: fix counting of waiting threads
QTBUG-21051 has a testcase where activeThreadCount() could actually end up at -1 (converted to an autotest in this commit). The reason was: start() calls tryStart() which returns false due to too many active threads (reserveThread() causes this), so it calls enqueueTask() - which actually wakes up the waiting thread, but it didn't decrement the number of waiting threads. Note that tryStart() is "if I can grab a waiting thread, enqueue task and wake it" while start(), in case tryStart() fails, wants to "enqueue, and then if I can grab a waiting thread, wake it". This is why enqueue shouldn't wake; waking must happen only if we can grab a thread (d->waitingThreads > 0). Task-number: QTBUG-21051 Change-Id: I3d98337103031c9bdf0bf365295f245be0c66aa7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthreadpool.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 31c3f5a256..9ef40a5209 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -180,6 +180,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
// recycle an available thread
--waitingThreads;
enqueueTask(task);
+ runnableReady.wakeOne();
return true;
}
@@ -218,7 +219,6 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
if (it != begin && priority > (*(it - 1)).second)
it = std::upper_bound(begin, --it, priority);
queue.insert(it - begin, qMakePair(runnable, priority));
- runnableReady.wakeOne();
}
int QThreadPoolPrivate::activeThreadCount() const
@@ -456,8 +456,14 @@ void QThreadPool::start(QRunnable *runnable, int priority)
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
- if (!d->tryStart(runnable))
+ if (!d->tryStart(runnable)) {
d->enqueueTask(runnable, priority);
+
+ if (d->waitingThreads > 0) {
+ --d->waitingThreads;
+ d->runnableReady.wakeOne();
+ }
+ }
}
/*!