summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/thread
diff options
context:
space:
mode:
authorNick Shaforostoff <shafff@ukr.net>2014-06-16 18:50:12 +0300
committerNick Shaforostoff <shafff@ukr.net>2014-12-24 15:01:36 +0100
commit5b11e43e9f7551b9cb1ea7a6effdcab4bfa6b8c9 (patch)
tree8a51cb9b664e355ec9e89ad648f20344eaea10d9 /tests/auto/corelib/thread
parent6475462c6fdf28f40a35cb6926b2f1f58187eb8a (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.cpp51
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;