diff options
author | Liang Qi <liang.qi@qt.io> | 2017-02-17 20:10:34 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-02-17 20:10:34 +0100 |
commit | bc4cd465dd5df82e13f3c7709166ee11289d219f (patch) | |
tree | d6323aaed6383e589fbefb6057648c22bb187c76 /tests/auto/corelib/thread | |
parent | 43daefb0962794b2df256cae1098e889b9b36f12 (diff) | |
parent | 07745d7bfbf6c8d83e0243150d8ce934675dea87 (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
qmake/Makefile.unix
Change-Id: Ia18e391198222eef34ffa2df6f683e052058d032
Diffstat (limited to 'tests/auto/corelib/thread')
4 files changed, 61 insertions, 18 deletions
diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST new file mode 100644 index 0000000000..22e30d0fd6 --- /dev/null +++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST @@ -0,0 +1,2 @@ +[tryAcquireWithTimeout:0.2s] +windows diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index a33417c7da..ba470a77c9 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -368,16 +368,18 @@ public: void run(); }; +static const int Timeout = 60 * 1000; // 1min + void Producer::run() { for (int i = 0; i < DataSize; ++i) { - freeSpace.acquire(); + QVERIFY(freeSpace.tryAcquire(1, Timeout)); buffer[i % BufferSize] = alphabet[i % AlphabetSize]; usedSpace.release(); } for (int i = 0; i < DataSize; ++i) { if ((i % ProducerChunkSize) == 0) - freeSpace.acquire(ProducerChunkSize); + QVERIFY(freeSpace.tryAcquire(ProducerChunkSize, Timeout)); buffer[i % BufferSize] = alphabet[i % AlphabetSize]; if ((i % ProducerChunkSize) == (ProducerChunkSize - 1)) usedSpace.release(ProducerChunkSize); diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 3bc3f8a759..5b7242fddb 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -958,51 +958,88 @@ void tst_QThreadPool::clear() void tst_QThreadPool::cancel() { QSemaphore sem(0); + QSemaphore startedThreads(0); + + class SemaphoreReleaser + { + QSemaphore &sem; + int n; + Q_DISABLE_COPY(SemaphoreReleaser) + public: + explicit SemaphoreReleaser(QSemaphore &sem, int n) + : sem(sem), n(n) {} + + ~SemaphoreReleaser() + { + sem.release(n); + } + }; + class BlockingRunnable : public QRunnable { public: QSemaphore & sem; - int & dtorCounter; - int & runCounter; + QSemaphore &startedThreads; + QAtomicInt &dtorCounter; + QAtomicInt &runCounter; int dummy; - BlockingRunnable(QSemaphore & s, int & c, int & r) : sem(s), dtorCounter(c), runCounter(r){} - ~BlockingRunnable(){dtorCounter++;} + + explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r) + : sem(s), startedThreads(started), dtorCounter(c), runCounter(r){} + + ~BlockingRunnable() + { + dtorCounter.fetchAndAddRelaxed(1); + } + void run() { - runCounter++; + startedThreads.release(); + runCounter.fetchAndAddRelaxed(1); sem.acquire(); count.ref(); } }; - typedef BlockingRunnable* BlockingRunnablePtr; + + enum { + MaxThreadCount = 3, + OverProvisioning = 2, + runs = MaxThreadCount * OverProvisioning + }; QThreadPool threadPool; - threadPool.setMaxThreadCount(3); - int runs = 2 * threadPool.maxThreadCount(); - BlockingRunnablePtr* runnables = new BlockingRunnablePtr[runs]; + threadPool.setMaxThreadCount(MaxThreadCount); + BlockingRunnable *runnables[runs]; + + // ensure that the QThreadPool doesn't deadlock if any of the checks fail + // and cause an early return: + const SemaphoreReleaser semReleaser(sem, runs); + count.store(0); - int dtorCounter = 0; - int runCounter = 0; + QAtomicInt dtorCounter = 0; + QAtomicInt runCounter = 0; for (int i = 0; i < runs; i++) { - runnables[i] = new BlockingRunnable(sem, dtorCounter, runCounter); + runnables[i] = new BlockingRunnable(sem, startedThreads, 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]); } + // wait for all worker threads to have started up: + QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */)); + 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); + QCOMPARE(dtorCounter.load(), runs - threadPool.maxThreadCount() - 1); sem.release(threadPool.maxThreadCount()); threadPool.waitForDone(); - QCOMPARE(runCounter, threadPool.maxThreadCount()); + QCOMPARE(runCounter.load(), threadPool.maxThreadCount()); QCOMPARE(count.load(), threadPool.maxThreadCount()); - QCOMPARE(dtorCounter, runs-2); + QCOMPARE(dtorCounter.load(), 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() diff --git a/tests/auto/corelib/thread/qwaitcondition/BLACKLIST b/tests/auto/corelib/thread/qwaitcondition/BLACKLIST new file mode 100644 index 0000000000..3ff336576b --- /dev/null +++ b/tests/auto/corelib/thread/qwaitcondition/BLACKLIST @@ -0,0 +1,2 @@ +[wakeOne] +windows |