diff options
author | Nick Shaforostoff <shafff@ukr.net> | 2014-06-16 18:50:12 +0300 |
---|---|---|
committer | Nick Shaforostoff <shafff@ukr.net> | 2014-12-24 15:01:36 +0100 |
commit | 5b11e43e9f7551b9cb1ea7a6effdcab4bfa6b8c9 (patch) | |
tree | 8a51cb9b664e355ec9e89ad648f20344eaea10d9 /tests/auto/corelib/thread | |
parent | 6475462c6fdf28f40a35cb6926b2f1f58187eb8a (diff) |
QThreadPool::cancel() to remove individual jobs from the job queue.
[ChangeLog][QtCore][QThreadPool] Added QThreadPool::cancel() which allows
removing from the job queue a job that hasn't been started yet.
Change-Id: Ib8f1c1f32a34f5eec8338c641d820b928e470164
Reviewed-by: Nick Shaforostoff <shafff@ukr.net>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'tests/auto/corelib/thread')
-rw-r--r-- | tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 9c2c8bf12a..1f1cf1db0c 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -92,6 +92,7 @@ private slots: void priorityStart(); void waitForDone(); void clear(); + void cancel(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); @@ -958,6 +959,56 @@ void tst_QThreadPool::clear() QCOMPARE(count.load(), threadPool.maxThreadCount()); } +void tst_QThreadPool::cancel() +{ + QSemaphore sem(0); + class BlockingRunnable : public QRunnable + { + public: + QSemaphore & sem; + int & dtorCounter; + int & runCounter; + int dummy; + BlockingRunnable(QSemaphore & s, int & c, int & r) : sem(s), dtorCounter(c), runCounter(r){} + ~BlockingRunnable(){dtorCounter++;} + void run() + { + runCounter++; + sem.acquire(); + count.ref(); + } + }; + typedef BlockingRunnable* BlockingRunnablePtr; + + QThreadPool threadPool; + threadPool.setMaxThreadCount(3); + int runs = 2 * threadPool.maxThreadCount(); + BlockingRunnablePtr* runnables = new BlockingRunnablePtr[runs]; + count.store(0); + int dtorCounter = 0; + int runCounter = 0; + for (int i = 0; i < runs; i++) { + runnables[i] = new BlockingRunnable(sem, dtorCounter, runCounter); + runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not + threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue + threadPool.start(runnables[i]); + } + for (int i = 0; i < runs; i++) { + threadPool.cancel(runnables[i]); + } + runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs + runnables[runs-1]->dummy = 0; + QCOMPARE(dtorCounter, runs-threadPool.maxThreadCount()-1); + sem.release(threadPool.maxThreadCount()); + threadPool.waitForDone(); + QCOMPARE(runCounter, threadPool.maxThreadCount()); + QCOMPARE(count.load(), threadPool.maxThreadCount()); + QCOMPARE(dtorCounter, runs-2); + delete runnables[0]; //if the pool deletes them then we'll get double-free crash + delete runnables[runs-1]; + delete[] runnables; +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; |