diff options
author | Thomas Sondergaard <ts@medical-insight.com> | 2010-05-26 08:52:19 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-05-26 08:52:41 (GMT) |
commit | 497cd2c5dfda11fff9233fc951813d6b84c78eed (patch) | |
tree | f3b4ce78abbdb90c444f87111e6caa8f09153cfb | |
parent | 0218fb14f3f05df746d7730f45a6137b33029dad (diff) | |
download | Qt-497cd2c5dfda11fff9233fc951813d6b84c78eed.zip Qt-497cd2c5dfda11fff9233fc951813d6b84c78eed.tar.gz Qt-497cd2c5dfda11fff9233fc951813d6b84c78eed.tar.bz2 |
Added QThreadPool::waitForDone(int msecs)
Merge-request: 641
Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
Reviewed-by: Morten Sorvig
Task-number: QTBUG-2695
-rw-r--r-- | src/corelib/concurrent/qthreadpool.cpp | 34 | ||||
-rw-r--r-- | src/corelib/concurrent/qthreadpool.h | 1 | ||||
-rw-r--r-- | src/corelib/concurrent/qthreadpool_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qthreadpool/tst_qthreadpool.cpp | 27 |
4 files changed, 60 insertions, 4 deletions
diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp index 9e4189e..f25a494 100644 --- a/src/corelib/concurrent/qthreadpool.cpp +++ b/src/corelib/concurrent/qthreadpool.cpp @@ -41,6 +41,7 @@ #include "qthreadpool.h" #include "qthreadpool_p.h" +#include "qelapsedtimer.h" #ifndef QT_NO_THREAD @@ -288,11 +289,21 @@ void QThreadPoolPrivate::reset() isExiting = false; } -void QThreadPoolPrivate::waitForDone() +bool QThreadPoolPrivate::waitForDone(int msecs) { QMutexLocker locker(&mutex); - while (!(queue.isEmpty() && activeThreads == 0)) - noActiveThreads.wait(locker.mutex()); + if (msecs < 0) { + while (!(queue.isEmpty() && activeThreads == 0)) + noActiveThreads.wait(locker.mutex()); + } else { + QElapsedTimer timer; + timer.start(); + int t; + while (!(queue.isEmpty() && activeThreads == 0) && + ((t = msecs - timer.elapsed()) > 0)) + noActiveThreads.wait(locker.mutex(), t); + } + return queue.isEmpty() && activeThreads == 0; } /*! \internal @@ -617,6 +628,23 @@ void QThreadPool::waitForDone() d->reset(); } +/*! + \overload waitForDone() + \since 4.8 + + Waits up to \a msecs milliseconds for all threads to exit and removes all + threads from the thread pool. Returns true if all threads were removed; + otherwise it returns false. +*/ +bool QThreadPool::waitForDone(int msecs) +{ + Q_D(QThreadPool); + bool rc = d->waitForDone(msecs); + if (rc) + d->reset(); + return rc; +} + QT_END_NAMESPACE #endif diff --git a/src/corelib/concurrent/qthreadpool.h b/src/corelib/concurrent/qthreadpool.h index cc1e059..0bd1884 100644 --- a/src/corelib/concurrent/qthreadpool.h +++ b/src/corelib/concurrent/qthreadpool.h @@ -85,6 +85,7 @@ public: void releaseThread(); void waitForDone(); + bool waitForDone(int msecs); }; QT_END_NAMESPACE diff --git a/src/corelib/concurrent/qthreadpool_p.h b/src/corelib/concurrent/qthreadpool_p.h index 8a2cf98..3d2d6be 100644 --- a/src/corelib/concurrent/qthreadpool_p.h +++ b/src/corelib/concurrent/qthreadpool_p.h @@ -82,7 +82,7 @@ public: void startThread(QRunnable *runnable = 0); void reset(); - void waitForDone(); + bool waitForDone(int msecs = -1); bool startFrontRunnable(); void stealRunnable(QRunnable *); diff --git a/tests/auto/qthreadpool/tst_qthreadpool.cpp b/tests/auto/qthreadpool/tst_qthreadpool.cpp index 7c8b410..cd6070f 100644 --- a/tests/auto/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/qthreadpool/tst_qthreadpool.cpp @@ -89,6 +89,7 @@ private slots: void tryStartPeakThreadCount(); void tryStartCount(); void waitForDone(); + void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); }; @@ -774,6 +775,32 @@ void tst_QThreadPool::waitForDone() } } +void tst_QThreadPool::waitForDoneTimeout() +{ + class BlockedTask : public QRunnable + { + public: + QMutex mutex; + BlockedTask() { setAutoDelete(false); } + + void run() + { + mutex.lock(); + mutex.unlock(); + QTest::qSleep(50); + } + }; + + QThreadPool threadPool; + + BlockedTask *task = new BlockedTask; + task->mutex.lock(); + threadPool.start(task); + QVERIFY(!threadPool.waitForDone(100)); + task->mutex.unlock(); + QVERIFY(threadPool.waitForDone(400)); +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; |