diff options
author | David Faure <david.faure@kdab.com> | 2013-06-21 08:32:17 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-15 11:42:27 (GMT) |
commit | 605647f2b8a6c8d4f700732a7fcdb1dec3459231 (patch) | |
tree | 6be7022dec15c93aac99e4557ebcebc68b72b483 /src | |
parent | 521ea9cc0e4014ce5186c727ba30026d7b7edc60 (diff) | |
download | Qt-605647f2b8a6c8d4f700732a7fcdb1dec3459231.zip Qt-605647f2b8a6c8d4f700732a7fcdb1dec3459231.tar.gz Qt-605647f2b8a6c8d4f700732a7fcdb1dec3459231.tar.bz2 |
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
Backport from qtbase/dacf9961da86751a59da0e84bc943fe0d1c8d95b
Change-Id: I1e437da27b733a72b48ff1b6f2b78f81a7ed129b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/concurrent/qthreadpool.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp index 5435aef..26a5337 100644 --- a/src/corelib/concurrent/qthreadpool.cpp +++ b/src/corelib/concurrent/qthreadpool.cpp @@ -187,6 +187,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) QList<QPair<QRunnable *, int> >::iterator at = qUpperBound(queue.begin(), queue.end(), priority); queue.insert(at, qMakePair(runnable, priority)); - runnableReady.wakeOne(); } int QThreadPoolPrivate::activeThreadCount() const @@ -471,8 +471,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(); + } + } } /*! |