summaryrefslogtreecommitdiffstats
path: root/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp')
-rw-r--r--tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp139
1 files changed, 102 insertions, 37 deletions
diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
index 1b0b9577cf..0bc2961903 100644
--- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
+++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qtconcurrentrun.h>
#include <QFuture>
#include <QMutex>
@@ -35,12 +10,15 @@
#include <QTimer>
#include <QFutureSynchronizer>
+#include <QtTest/private/qemulationdetector_p.h>
+
using namespace QtConcurrent;
class tst_QtConcurrentRun: public QObject
{
Q_OBJECT
private slots:
+ void initTestCase();
void runLightFunction();
void runHeavyFunction();
void returnValue();
@@ -64,6 +42,9 @@ private slots:
void moveOnlyType();
void crefFunction();
void customPromise();
+ void nonDefaultConstructibleValue();
+ void nullThreadPool();
+ void nullThreadPoolNoLeak();
};
void light()
@@ -105,6 +86,13 @@ void heavy()
qDebug("done function");
}
+void tst_QtConcurrentRun::initTestCase()
+{
+ // proxy check for QEMU; catches slightly more though
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Runs into spurious crashes on QEMU -- QTBUG-106906");
+}
+
void tst_QtConcurrentRun::runLightFunction()
{
qDebug("starting function");
@@ -678,10 +666,10 @@ void tst_QtConcurrentRun::implicitConvertibleTypes()
{
QThreadPool pool;
- double d;
+ double d = 0.0;
run(doubleFunction, d).waitForFinished();
run(&pool, doubleFunction, d).waitForFinished();
- int i;
+ int i = 0;
run(doubleFunction, d).waitForFinished();
run(&pool, doubleFunction, d).waitForFinished();
run(doubleFunction, i).waitForFinished();
@@ -827,7 +815,7 @@ public:
void run() override {
int iter = 60;
while (--iter && !cancel.loadRelaxed())
- QThread::currentThread()->msleep(25);
+ QThread::currentThread()->sleep(std::chrono::milliseconds{25});
}
};
@@ -1101,12 +1089,25 @@ void report3(QPromise<int> &promise)
promise.addResult(1);
}
+static void staticReport3(QPromise<int> &promise)
+{
+ promise.addResult(0);
+ promise.addResult(2);
+ promise.addResult(1);
+}
+
void reportN(QPromise<double> &promise, int n)
{
for (int i = 0; i < n; ++i)
promise.addResult(0);
}
+static void staticReportN(QPromise<double> &promise, int n)
+{
+ for (int i = 0; i < n; ++i)
+ promise.addResult(0);
+}
+
void reportString1(QPromise<QString> &promise, const QString &s)
{
promise.addResult(s);
@@ -1180,11 +1181,21 @@ void tst_QtConcurrentRun::withPromise()
QCOMPARE(run(report3).results(),
QList<int>({0, 2, 1}));
- QCOMPARE(run(reportN, 4).results(),
- QList<double>({0, 0, 0, 0}));
+ QCOMPARE(run(&staticReport3).results(),
+ QList<int>({0, 2, 1}));
+ QCOMPARE(run(staticReport3).results(),
+ QList<int>({0, 2, 1}));
+
+ QCOMPARE(run(&reportN, 2).results(),
+ QList<double>({0, 0}));
QCOMPARE(run(reportN, 2).results(),
QList<double>({0, 0}));
+ QCOMPARE(run(&staticReportN, 2).results(),
+ QList<double>({0, 0}));
+ QCOMPARE(run(staticReportN, 2).results(),
+ QList<double>({0, 0}));
+
QString s = QLatin1String("string");
const QString &crs = QLatin1String("cr string");
const QString cs = QLatin1String("c string");
@@ -1271,11 +1282,21 @@ void tst_QtConcurrentRun::withPromiseInThreadPool()
QCOMPARE(run(pool.data(), report3).results(),
QList<int>({0, 2, 1}));
- QCOMPARE(run(pool.data(), reportN, 4).results(),
- QList<double>({0, 0, 0, 0}));
+ QCOMPARE(run(pool.data(), &staticReport3).results(),
+ QList<int>({0, 2, 1}));
+ QCOMPARE(run(pool.data(), staticReport3).results(),
+ QList<int>({0, 2, 1}));
+
+ QCOMPARE(run(pool.data(), &reportN, 2).results(),
+ QList<double>({0, 0}));
QCOMPARE(run(pool.data(), reportN, 2).results(),
QList<double>({0, 0}));
+ QCOMPARE(run(pool.data(), &staticReportN, 2).results(),
+ QList<double>({0, 0}));
+ QCOMPARE(run(pool.data(), staticReportN, 2).results(),
+ QList<double>({0, 0}));
+
QString s = QLatin1String("string");
const QString &crs = QLatin1String("cr string");
const QString cs = QLatin1String("c string");
@@ -1405,7 +1426,7 @@ void tst_QtConcurrentRun::withPromiseAndThen()
setFlag(syncEnd);
future.waitForFinished();
- QCOMPARE(future.results().count(), 0);
+ QCOMPARE(future.results().size(), 0);
QVERIFY(runExecuted);
QVERIFY(!cancelReceivedBeforeSync);
QVERIFY(cancelReceivedAfterSync);
@@ -1425,7 +1446,7 @@ void tst_QtConcurrentRun::withPromiseAndThen()
setFlag(syncEnd);
resultFuture.waitForFinished();
- QCOMPARE(future.results().count(), 1);
+ QCOMPARE(future.results().size(), 1);
QCOMPARE(future.result(), 1);
QVERIFY(runExecuted);
QVERIFY(thenExecuted);
@@ -1448,7 +1469,7 @@ void tst_QtConcurrentRun::withPromiseAndThen()
setFlag(syncEnd);
resultFuture.waitForFinished();
- QCOMPARE(future.results().count(), 0);
+ QCOMPARE(future.results().size(), 0);
QVERIFY(runExecuted);
QVERIFY(!thenExecuted);
QVERIFY(cancelExecuted);
@@ -1564,6 +1585,50 @@ void tst_QtConcurrentRun::customPromise()
QCOMPARE(p.future().progressMaximum(), 10);
}
+void tst_QtConcurrentRun::nonDefaultConstructibleValue()
+{
+ struct NonDefaultConstructible
+ {
+ explicit NonDefaultConstructible(int v) : value(v) { }
+ int value = 0;
+ };
+
+ auto future = QtConcurrent::run([] { return NonDefaultConstructible(42); });
+ QCOMPARE(future.result().value, 42);
+}
+
+// QTBUG-98901
+void tst_QtConcurrentRun::nullThreadPool()
+{
+ QThreadPool *pool = nullptr;
+ std::atomic<bool> isInvoked = false;
+ auto future = run(pool, [&] { isInvoked = true; });
+ future.waitForFinished();
+ QVERIFY(future.isCanceled());
+ QVERIFY(!isInvoked);
+}
+
+struct LifetimeChecker
+{
+ LifetimeChecker() { ++count; }
+ LifetimeChecker(const LifetimeChecker &) { ++count; }
+ ~LifetimeChecker() { --count; }
+
+ void operator()() { }
+
+ static std::atomic<int> count;
+};
+std::atomic<int> LifetimeChecker::count = 0;
+
+void tst_QtConcurrentRun::nullThreadPoolNoLeak()
+{
+ {
+ QThreadPool *pool = nullptr;
+ auto future = run(pool, LifetimeChecker());
+ future.waitForFinished();
+ }
+ QCOMPARE(LifetimeChecker::count, 0);
+}
QTEST_MAIN(tst_QtConcurrentRun)
#include "tst_qtconcurrentrun.moc"