summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/thread')
-rw-r--r--tests/auto/corelib/thread/qmutex/tst_qmutex.cpp2
-rw-r--r--tests/auto/corelib/thread/qsemaphore/BLACKLIST5
-rw-r--r--tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp6
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp92
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/test/test.pro2
5 files changed, 99 insertions, 8 deletions
diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
index 3e4a6eb7e7..0962001741 100644
--- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
+++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
@@ -102,7 +102,7 @@ void tst_QMutex::convertToMilliseconds_data()
auto add = [](TimeUnit unit, double d, long long i, qint64 expected) {
const QScopedArrayPointer<char> enumName(QTest::toString(unit));
- QTest::newRow(qPrintable(QString::asprintf("%s:%f:%lld", enumName.data(), d, i)))
+ QTest::addRow("%s:%f:%lld", enumName.data(), d, i)
<< unit << d << qint64(i) << expected;
};
diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
index 9f6f6e3ba6..22e30d0fd6 100644
--- a/tests/auto/corelib/thread/qsemaphore/BLACKLIST
+++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
@@ -1,3 +1,2 @@
-# Times out randomly on linux, windows, osx
-[tryAcquireWithTimeout]
-*
+[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 e984618bdb..2970b2e118 100644
--- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp
+++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp
@@ -202,8 +202,8 @@ void tst_QSemaphore::tryAcquireWithTimeout_data()
{
QTest::addColumn<int>("timeout");
- QTest::newRow("1s") << 1000;
- QTest::newRow("10s") << 10000;
+ QTest::newRow("0.2s") << 200;
+ QTest::newRow("2s") << 2000;
}
void tst_QSemaphore::tryAcquireWithTimeout()
@@ -212,7 +212,7 @@ void tst_QSemaphore::tryAcquireWithTimeout()
// timers are not guaranteed to be accurate down to the last millisecond,
// so we permit the elapsed times to be up to this far from the expected value.
- int fuzz = 50;
+ int fuzz = 50 + (timeout / 20);
QSemaphore semaphore;
QElapsedTimer time;
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 5b7242fddb..fdc4ecb5c8 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -89,6 +89,7 @@ private slots:
void waitForDone();
void clear();
void cancel();
+ void tryTake();
void waitForDoneTimeout();
void destroyingWaitsForTasksToFinish();
void stressTest();
@@ -1042,6 +1043,97 @@ void tst_QThreadPool::cancel()
delete runnables[runs-1];
}
+void tst_QThreadPool::tryTake()
+{
+ 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;
+ QSemaphore &startedThreads;
+ QAtomicInt &dtorCounter;
+ QAtomicInt &runCounter;
+ int dummy;
+
+ explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
+ : sem(s), startedThreads(started), dtorCounter(c), runCounter(r) {}
+
+ ~BlockingRunnable()
+ {
+ dtorCounter.fetchAndAddRelaxed(1);
+ }
+
+ void run() override
+ {
+ startedThreads.release();
+ runCounter.fetchAndAddRelaxed(1);
+ sem.acquire();
+ count.ref();
+ }
+ };
+
+ enum {
+ MaxThreadCount = 3,
+ OverProvisioning = 2,
+ Runs = MaxThreadCount * OverProvisioning
+ };
+
+ QThreadPool threadPool;
+ 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);
+ QAtomicInt dtorCounter = 0;
+ QAtomicInt runCounter = 0;
+ for (int i = 0; i < Runs; i++) {
+ 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
+ QVERIFY(!threadPool.tryTake(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 < MaxThreadCount; ++i) {
+ // check taking runnables doesn't work once they were started:
+ QVERIFY(!threadPool.tryTake(runnables[i]));
+ }
+ for (int i = MaxThreadCount; i < Runs ; ++i) {
+ QVERIFY(threadPool.tryTake(runnables[i]));
+ delete runnables[i];
+ }
+
+ runnables[0]->dummy = 0; // valgrind will catch this if tryTake() is crazy enough to delete currently running jobs
+ QCOMPARE(dtorCounter.load(), int(Runs - MaxThreadCount));
+ sem.release(MaxThreadCount);
+ threadPool.waitForDone();
+ QCOMPARE(runCounter.load(), int(MaxThreadCount));
+ QCOMPARE(count.load(), int(MaxThreadCount));
+ QCOMPARE(dtorCounter.load(), int(Runs - 1));
+ delete runnables[0]; // if the pool deletes them then we'll get double-free crash
+}
+
void tst_QThreadPool::destroyingWaitsForTasksToFinish()
{
QTime total, pass;
diff --git a/tests/auto/corelib/thread/qthreadstorage/test/test.pro b/tests/auto/corelib/thread/qthreadstorage/test/test.pro
index b9d661a9af..1a1fede186 100644
--- a/tests/auto/corelib/thread/qthreadstorage/test/test.pro
+++ b/tests/auto/corelib/thread/qthreadstorage/test/test.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = ../tst_qthreadstorage
-CONFIG -= app_bundle debug_and_release_target
+CONFIG -= debug_and_release_target
CONFIG += console
QT = core testlib
SOURCES = ../tst_qthreadstorage.cpp