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/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/thread/qatomicint/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp17
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt18
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp6
-rw-r--r--tests/auto/corelib/thread/qfuture/.prev_CMakeLists.txt14
-rw-r--r--tests/auto/corelib/thread/qfuture/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/thread/qfuture/qfuture.pro1
-rw-r--r--tests/auto/corelib/thread/qfuture/tst_qfuture.cpp1132
-rw-r--r--tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qmutex/CMakeLists.txt18
-rw-r--r--tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qreadlocker/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qresultstore/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/thread/qresultstore/qresultstore.pro1
-rw-r--r--tests/auto/corelib/thread/qsemaphore/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qthread/.prev_CMakeLists.txt16
-rw-r--r--tests/auto/corelib/thread/qthread/CMakeLists.txt18
-rw-r--r--tests/auto/corelib/thread/qthreadonce/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/thread/qthreadpool/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/.prev_CMakeLists.txt15
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/thread/qwritelocker/CMakeLists.txt10
44 files changed, 1655 insertions, 19 deletions
diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt
new file mode 100644
index 0000000000..d07c583a77
--- /dev/null
+++ b/tests/auto/corelib/thread/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Generated from thread.pro.
+
+if(QT_FEATURE_thread)
+ add_subdirectory(qatomicint)
+ add_subdirectory(qatomicinteger)
+ add_subdirectory(qatomicpointer)
+ add_subdirectory(qresultstore)
+ add_subdirectory(qfuture)
+ add_subdirectory(qfuturesynchronizer)
+ add_subdirectory(qmutex)
+ add_subdirectory(qmutexlocker)
+ add_subdirectory(qreadlocker)
+ add_subdirectory(qreadwritelock)
+ add_subdirectory(qsemaphore)
+ add_subdirectory(qthread)
+ add_subdirectory(qthreadonce)
+ add_subdirectory(qthreadpool)
+ add_subdirectory(qthreadstorage)
+ add_subdirectory(qwaitcondition)
+ add_subdirectory(qwritelocker)
+endif()
+if(TARGET Qt::Concurrent)
+ add_subdirectory(qfuturewatcher)
+endif()
diff --git a/tests/auto/corelib/thread/qatomicint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt
new file mode 100644
index 0000000000..1a084fb28c
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qatomicint.pro.
+
+#####################################################################
+## tst_qatomicint Test:
+#####################################################################
+
+add_qt_test(tst_qatomicint
+ SOURCES
+ tst_qatomicint.cpp
+)
diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
index bef491d5f0..22ee7d17b7 100644
--- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
+++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
@@ -237,28 +237,23 @@ template <typename T> struct TypeInStruct { T type; };
void tst_QAtomicInt::alignment()
{
-#ifdef Q_ALIGNOF
- // this will cause a build error if the alignment isn't the same
- char dummy1[Q_ALIGNOF(QBasicAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
- char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
- (void)dummy1; (void)dummy2;
+ Q_STATIC_ASSERT(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
+ Q_STATIC_ASSERT(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
#ifdef Q_ATOMIC_INT32_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<int>), Q_ALIGNOF(TypeInStruct<int>));
+ QCOMPARE(alignof(QBasicAtomicInteger<int>), alignof(TypeInStruct<int>));
#endif
#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<short>), Q_ALIGNOF(TypeInStruct<short>));
+ QCOMPARE(alignof(QBasicAtomicInteger<short>), alignof(TypeInStruct<short>));
#endif
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<char>), Q_ALIGNOF(TypeInStruct<char>));
+ QCOMPARE(alignof(QBasicAtomicInteger<char>), alignof(TypeInStruct<char>));
#endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<qlonglong>), Q_ALIGNOF(TypeInStruct<qlonglong>));
-#endif
-
+ QCOMPARE(alignof(QBasicAtomicInteger<qlonglong>), alignof(TypeInStruct<qlonglong>));
#endif
}
diff --git a/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt
new file mode 100644
index 0000000000..8f0637a4d2
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Generated from qatomicinteger.pro.
+
+add_subdirectory(char)
+add_subdirectory(char16_t)
+add_subdirectory(char32_t)
+add_subdirectory(int)
+add_subdirectory(long)
+add_subdirectory(qlonglong)
+add_subdirectory(qptrdiff)
+add_subdirectory(quintptr)
+add_subdirectory(qulonglong)
+add_subdirectory(schar)
+add_subdirectory(short)
+add_subdirectory(uchar)
+add_subdirectory(uint)
+add_subdirectory(ulong)
+add_subdirectory(ushort)
+add_subdirectory(wchar_t)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt
new file mode 100644
index 0000000000..6ccaf3291d
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from char.pro.
+
+#####################################################################
+## tst_qatomicinteger_char Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_char
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt
new file mode 100644
index 0000000000..d57d4b89dc
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from char16_t.pro.
+
+#####################################################################
+## tst_qatomicinteger_char16_t Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_char16_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char16_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char16_t
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt
new file mode 100644
index 0000000000..7e04c7864b
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from char32_t.pro.
+
+#####################################################################
+## tst_qatomicinteger_char32_t Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_char32_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char32_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char32_t
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt
new file mode 100644
index 0000000000..16332fcf3b
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from int.pro.
+
+#####################################################################
+## tst_qatomicinteger_int Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_int
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=int
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_int
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt
new file mode 100644
index 0000000000..17c2510ac2
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from long.pro.
+
+#####################################################################
+## tst_qatomicinteger_long Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_long
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=long
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_long
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt
new file mode 100644
index 0000000000..021b865e67
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from qlonglong.pro.
+
+#####################################################################
+## tst_qatomicinteger_qlonglong Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_qlonglong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qlonglong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qlonglong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt
new file mode 100644
index 0000000000..4beff29882
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from qptrdiff.pro.
+
+#####################################################################
+## tst_qatomicinteger_qptrdiff Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_qptrdiff
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qptrdiff
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qptrdiff
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt
new file mode 100644
index 0000000000..a5f9b7aef3
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from quintptr.pro.
+
+#####################################################################
+## tst_qatomicinteger_quintptr Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_quintptr
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=quintptr
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_quintptr
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt
new file mode 100644
index 0000000000..d2e1c31856
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from qulonglong.pro.
+
+#####################################################################
+## tst_qatomicinteger_qulonglong Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_qulonglong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qulonglong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qulonglong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt
new file mode 100644
index 0000000000..9354bbe2e2
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from schar.pro.
+
+#####################################################################
+## tst_qatomicinteger_schar Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_schar
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=schar
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_schar
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt
new file mode 100644
index 0000000000..07143ed431
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from short.pro.
+
+#####################################################################
+## tst_qatomicinteger_short Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_short
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=short
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_short
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt
new file mode 100644
index 0000000000..ebc64efea5
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from uchar.pro.
+
+#####################################################################
+## tst_qatomicinteger_uchar Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_uchar
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=uchar
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_uchar
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt
new file mode 100644
index 0000000000..561274da9d
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from uint.pro.
+
+#####################################################################
+## tst_qatomicinteger_uint Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_uint
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=uint
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_uint
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt
new file mode 100644
index 0000000000..c859818838
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from ulong.pro.
+
+#####################################################################
+## tst_qatomicinteger_ulong Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_ulong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=ulong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_ulong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt
new file mode 100644
index 0000000000..6608390b8e
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from ushort.pro.
+
+#####################################################################
+## tst_qatomicinteger_ushort Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_ushort
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=ushort
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_ushort
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt
new file mode 100644
index 0000000000..9c7e17f1bd
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from wchar_t.pro.
+
+#####################################################################
+## tst_qatomicinteger_wchar_t Test:
+#####################################################################
+
+add_qt_test(tst_qatomicinteger_wchar_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=wchar_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_wchar_t
+)
diff --git a/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt
new file mode 100644
index 0000000000..f400ad7b2e
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qatomicpointer.pro.
+
+#####################################################################
+## tst_qatomicpointer Test:
+#####################################################################
+
+add_qt_test(tst_qatomicpointer
+ SOURCES
+ tst_qatomicpointer.cpp
+)
diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
index a699cf6202..9e12e7ccce 100644
--- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
+++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
@@ -108,11 +108,7 @@ void tst_QAtomicPointer::warningFree()
void tst_QAtomicPointer::alignment()
{
-#ifdef Q_ALIGNOF
- // this will cause a build error if the alignment isn't the same
- char dummy[Q_ALIGNOF(QBasicAtomicPointer<void>) == Q_ALIGNOF(void*) ? 1 : -1];
- (void)dummy;
-#endif
+ Q_STATIC_ASSERT(alignof(QBasicAtomicPointer<void>) == alignof(void*));
}
void tst_QAtomicPointer::constructor()
diff --git a/tests/auto/corelib/thread/qfuture/.prev_CMakeLists.txt b/tests/auto/corelib/thread/qfuture/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..6908bd678c
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuture/.prev_CMakeLists.txt
@@ -0,0 +1,14 @@
+# Generated from qfuture.pro.
+
+#####################################################################
+## tst_qfuture Test:
+#####################################################################
+
+qt_add_test(tst_qfuture
+ SOURCES
+ tst_qfuture.cpp
+ DEFINES
+ -QT_NO_JAVA_STYLE_ITERATORS
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt
new file mode 100644
index 0000000000..6fdfc977e9
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Generated from qfuture.pro.
+
+#####################################################################
+## tst_qfuture Test:
+#####################################################################
+
+qt_add_test(tst_qfuture
+ SOURCES
+ tst_qfuture.cpp
+# DEFINES
+# -QT_NO_JAVA_STYLE_ITERATORS
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qfuture/qfuture.pro b/tests/auto/corelib/thread/qfuture/qfuture.pro
index 1f21130af7..fe097edf20 100644
--- a/tests/auto/corelib/thread/qfuture/qfuture.pro
+++ b/tests/auto/corelib/thread/qfuture/qfuture.pro
@@ -2,5 +2,4 @@ CONFIG += testcase
TARGET = tst_qfuture
QT = core core-private testlib
SOURCES = tst_qfuture.cpp
-DEFINES += QT_STRICT_ITERATORS
DEFINES -= QT_NO_JAVA_STYLE_ITERATORS
diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
index a42454124e..1caa386638 100644
--- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
+++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
@@ -37,8 +37,12 @@
#include <qthreadpool.h>
#include <qexception.h>
#include <qrandom.h>
+#include <QtConcurrent/qtconcurrentrun.h>
#include <private/qfutureinterface_p.h>
+#include <vector>
+#include <memory>
+
// COM interface macro.
#if defined(Q_OS_WIN) && defined(interface)
# undef interface
@@ -94,6 +98,32 @@ private slots:
void nestedExceptions();
#endif
void nonGlobalThreadPool();
+
+ void then();
+ void thenOnCanceledFuture();
+#ifndef QT_NO_EXCEPTIONS
+ void thenOnExceptionFuture();
+ void thenThrows();
+ void onFailed();
+ void onFailedTestCallables();
+#endif
+ void takeResults();
+ void takeResult();
+ void runAndTake();
+ void resultsReadyAt_data();
+ void resultsReadyAt();
+private:
+ using size_type = std::vector<int>::size_type;
+ using UniquePtr = std::unique_ptr<int>;
+
+ static void testSingleResult(const UniquePtr &p);
+ static void testSingleResult(const std::vector<int> &v);
+ template<class T>
+ static void testSingleResult(const T &unknown);
+ template<class T>
+ static void testFutureTaken(QFuture<T> &noMoreFuture);
+ template<class T>
+ static void testTakeResults(QFuture<T> future, size_type resultCount);
};
void tst_QFuture::resultStore()
@@ -1166,7 +1196,6 @@ void tst_QFuture::iterators()
void tst_QFuture::iteratorsThread()
{
const int expectedResultCount = 10;
- const int delay = 10;
QFutureInterface<int> futureInterface;
// Create result producer thread. The results are
@@ -1391,6 +1420,23 @@ QFuture<void> createDerivedExceptionFuture()
return f;
}
+struct TestException
+{
+};
+
+QFuture<int> createCustomExceptionFuture()
+{
+ QFutureInterface<int> i;
+ i.reportStarted();
+ QFuture<int> f = i.future();
+ int r = 0;
+ i.reportResult(r);
+ auto exception = std::make_exception_ptr(TestException());
+ i.reportException(exception);
+ i.reportFinished();
+ return f;
+}
+
void tst_QFuture::exceptions()
{
// test throwing from waitForFinished
@@ -1475,6 +1521,18 @@ void tst_QFuture::exceptions()
}
QVERIFY(caught);
}
+
+ // Custom exceptions
+ {
+ QFuture<int> f = createCustomExceptionFuture();
+ bool caught = false;
+ try {
+ f.result();
+ } catch (const TestException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
}
class MyClass
@@ -1557,5 +1615,1077 @@ void tst_QFuture::nonGlobalThreadPool()
}
}
+void tst_QFuture::then()
+{
+ {
+ struct Add
+ {
+
+ static int addTwo(int arg) { return arg + 2; }
+
+ int operator()(int arg) const { return arg + 3; }
+ };
+
+ QFutureInterface<int> promise;
+ QFuture<int> then = promise.future()
+ .then([](int res) { return res + 1; }) // lambda
+ .then(Add::addTwo) // function
+ .then(Add()); // functor
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.result(), result + 6);
+ }
+
+ // then() on a ready future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ QFuture<int> then = promise.future()
+ .then([](int res1) { return res1 + 1; })
+ .then([](int res2) { return res2 + 2; })
+ .then([](int res3) { return res3 + 3; });
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.result(), result + 6);
+ }
+
+ // Continuation of QFuture<void>
+ {
+ int result = 0;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then([&]() { result += 1; })
+ .then([&]() { result += 2; })
+ .then([&]() { result += 3; });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(result, 6);
+ }
+
+ // Continuation returns QFuture<void>
+ {
+ QFutureInterface<int> promise;
+ int value;
+ QFuture<void> then =
+ promise.future().then([](int res) { return res * 2; }).then([&](int prevResult) {
+ value = prevResult;
+ });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 5;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(value, result * 2);
+ }
+
+ // Continuations taking a QFuture argument.
+ {
+ int value = 0;
+ QFutureInterface<int> promise;
+ QFuture<void> then = promise.future()
+ .then([](QFuture<int> f1) { return f1.result() + 1; })
+ .then([&](QFuture<int> f2) { value = f2.result() + 2; })
+ .then([&](QFuture<void> f3) {
+ QVERIFY(f3.isFinished());
+ value += 3;
+ });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(value, 6);
+ }
+
+ // Continuations use a new thread
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Async,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then([&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ QVERIFY(threadId1 == threadId2);
+ }
+
+ // Continuation inherits the launch policy of its parent (QtFuture::Launch::Sync)
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Sync,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then(QtFuture::Launch::Inherit,
+ [&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 == QThread::currentThreadId());
+ QVERIFY(threadId2 == QThread::currentThreadId());
+ QVERIFY(threadId1 == threadId2);
+ }
+
+ // Continuation inherits the launch policy of its parent (QtFuture::Launch::Async)
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Async,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then(QtFuture::Launch::Inherit,
+ [&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ }
+
+ // Continuations use a custom thread pool
+ {
+ QFutureInterface<void> promise;
+ QThreadPool pool;
+ QVERIFY(pool.waitForDone(0)); // pool is not busy yet
+ QSemaphore semaphore;
+ QFuture<void> then = promise.future().then(&pool, [&]() { semaphore.acquire(); });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ // Make sure the custom thread pool is busy on running the continuation
+ QVERIFY(!pool.waitForDone(0));
+ semaphore.release();
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.d.threadPool(), &pool);
+ }
+
+ // Continuation inherits parent's thread pool
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+
+ QThreadPool pool;
+ QFuture<void> then1 = promise.future().then(&pool, [&]() {
+ threadId1 = QThread::currentThreadId();
+ });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ then1.waitForFinished();
+ QVERIFY(pool.waitForDone()); // The pool is not busy after the first continuation is done
+
+ QSemaphore semaphore;
+ QFuture<void> then2 = then1.then(QtFuture::Launch::Inherit, [&]() {
+ semaphore.acquire();
+ threadId2 = QThread::currentThreadId();
+ });
+
+ QVERIFY(!pool.waitForDone(0)); // The pool is busy running the 2nd continuation
+
+ semaphore.release();
+ then2.waitForFinished();
+
+ QVERIFY(then2.isStarted());
+ QVERIFY(then2.isFinished());
+ QCOMPARE(then1.d.threadPool(), then2.d.threadPool());
+ QCOMPARE(then2.d.threadPool(), &pool);
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ }
+}
+
+void tst_QFuture::thenOnCanceledFuture()
+{
+ // Continuations on a canceled future
+ {
+ QFutureInterface<void> promise;
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then([&]() { ++thenResult; }).then([&]() { ++thenResult; });
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // QFuture gets canceled after continuations are set
+ {
+ QFutureInterface<void> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then([&]() { ++thenResult; }).then([&]() { ++thenResult; });
+
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Same with QtFuture::Launch::Async
+
+ // Continuations on a canceled future
+ {
+ QFutureInterface<void> promise;
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&]() { ++thenResult; }).then([&]() {
+ ++thenResult;
+ });
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // QFuture gets canceled after continuations are set
+ {
+ QFutureInterface<void> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&]() { ++thenResult; }).then([&]() {
+ ++thenResult;
+ });
+
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+}
+
+#ifndef QT_NO_EXCEPTIONS
+void tst_QFuture::thenOnExceptionFuture()
+{
+ {
+ QFutureInterface<int> promise;
+
+ int thenResult = 0;
+ QFuture<void> then = promise.future().then([&](int res) { thenResult = res; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Exception handled inside the continuation
+ {
+ QFutureInterface<int> promise;
+
+ bool caught = false;
+ bool caughtByContinuation = false;
+ bool success = false;
+ int thenResult = 0;
+ QFuture<void> then = promise.future()
+ .then([&](QFuture<int> res) {
+ try {
+ thenResult = res.result();
+ } catch (QException &) {
+ caughtByContinuation = true;
+ }
+ })
+ .then([&]() { success = true; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+
+ QCOMPARE(thenResult, 0);
+ QVERIFY(!caught);
+ QVERIFY(caughtByContinuation);
+ QVERIFY(success);
+ }
+
+ // Exception future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then = promise.future().then([&](int res) { thenResult = res; });
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Same with QtFuture::Launch::Async
+ {
+ QFutureInterface<int> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&](int res) { thenResult = res; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Exception future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&](int res) { thenResult = res; });
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+}
+
+template<class Exception, bool hasTestMsg = false>
+QFuture<void> createExceptionContinuation(QtFuture::Launch policy = QtFuture::Launch::Sync)
+{
+ QFutureInterface<void> promise;
+
+ auto then = promise.future().then(policy, [] {
+ if constexpr (hasTestMsg)
+ throw Exception("TEST");
+ else
+ throw Exception();
+ });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ return then;
+}
+
+void tst_QFuture::thenThrows()
+{
+ // Continuation throws a QException
+ {
+ auto future = createExceptionContinuation<QException>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+
+ // Continuation throws an exception derived from QException
+ {
+ auto future = createExceptionContinuation<DerivedException>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ } catch (const std::exception &) {
+ QFAIL("The exception should be caught by the above catch block.");
+ }
+
+ QVERIFY(caught);
+ }
+
+ // Continuation throws std::exception
+ {
+ auto future = createExceptionContinuation<std::runtime_error, true>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ QFAIL("The exception should be caught by the below catch block.");
+ } catch (const std::exception &e) {
+ QCOMPARE(e.what(), "TEST");
+ caught = true;
+ }
+
+ QVERIFY(caught);
+ }
+
+ // Same with QtFuture::Launch::Async
+ {
+ auto future = createExceptionContinuation<QException>(QtFuture::Launch::Async);
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+}
+
+void tst_QFuture::onFailed()
+{
+ // Ready exception void future
+ {
+ int checkpoint = 0;
+ auto future = createExceptionFuture().then([&] { checkpoint = 1; }).onFailed([&] {
+ checkpoint = 2;
+ });
+
+ try {
+ future.waitForFinished();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 2);
+ }
+
+ // std::exception handler
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw std::exception();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // then() throws an exception derived from QException
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw DerivedException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 1);
+ QCOMPARE(res, -1);
+ }
+
+ // then() throws a custom exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw TestException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 3);
+ QCOMPARE(res, -1);
+ }
+
+ // Custom exception handler
+ {
+ struct TestException
+ {
+ };
+
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw TestException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const TestException &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // Handle all exceptions
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&] {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const QException &) {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 1);
+ QCOMPARE(res, -1);
+ }
+
+ // Handler throws exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ throw QException();
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // No handler for exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 1;
+ throw std::exception();
+ return -1;
+ })
+ .onFailed([&](QException &) {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 3);
+ QCOMPARE(res, 0);
+ }
+}
+
+template<class Callable>
+bool runForCallable(Callable &&handler)
+{
+ QFuture<int> future = createExceptionResultFuture()
+ .then([&](int) { return 1; })
+ .onFailed(std::forward<Callable>(handler));
+
+ int res = 0;
+ try {
+ res = future.result();
+ } catch (...) {
+ return false;
+ }
+ return res == -1;
+}
+
+int foo()
+{
+ return -1;
+}
+
+void tst_QFuture::onFailedTestCallables()
+{
+ QVERIFY(runForCallable([&] { return -1; }));
+ QVERIFY(runForCallable(foo));
+ QVERIFY(runForCallable(&foo));
+
+ std::function<int()> func = foo;
+ QVERIFY(runForCallable(func));
+
+ struct Functor1
+ {
+ int operator()() { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor1()));
+ QVERIFY(runForCallable(Functor1::foo));
+
+ struct Functor2
+ {
+ int operator()() const { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor2()));
+
+ struct Functor3
+ {
+ int operator()() const noexcept { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor3()));
+}
+
+#endif // QT_NO_EXCEPTIONS
+
+void tst_QFuture::testSingleResult(const UniquePtr &p)
+{
+ QVERIFY(p.get() != nullptr);
+}
+
+void tst_QFuture::testSingleResult(const std::vector<int> &v)
+{
+ QVERIFY(!v.empty());
+}
+
+template<class T>
+void tst_QFuture::testSingleResult(const T &unknown)
+{
+ Q_UNUSED(unknown);
+}
+
+
+template<class T>
+void tst_QFuture::testFutureTaken(QFuture<T> &noMoreFuture)
+{
+ QCOMPARE(noMoreFuture.isValid(), false);
+ QCOMPARE(noMoreFuture.resultCount(), 0);
+ QCOMPARE(noMoreFuture.isStarted(), false);
+ QCOMPARE(noMoreFuture.isRunning(), false);
+ QCOMPARE(noMoreFuture.isPaused(), false);
+ QCOMPARE(noMoreFuture.isFinished(), false);
+ QCOMPARE(noMoreFuture.progressValue(), 0);
+}
+
+template<class T>
+void tst_QFuture::testTakeResults(QFuture<T> future, size_type resultCount)
+{
+ auto copy = future;
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isValid());
+ QCOMPARE(size_type(future.resultCount()), resultCount);
+ QVERIFY(copy.isFinished());
+ QVERIFY(copy.isValid());
+ QCOMPARE(size_type(copy.resultCount()), resultCount);
+
+ auto vec = future.takeResults();
+ QCOMPARE(vec.size(), resultCount);
+
+ for (const auto &r : vec) {
+ testSingleResult(r);
+ if (QTest::currentTestFailed())
+ return;
+ }
+
+ testFutureTaken(future);
+ if (QTest::currentTestFailed())
+ return;
+ testFutureTaken(copy);
+}
+
+void tst_QFuture::takeResults()
+{
+ // Test takeResults() for movable types (whether or not copyable).
+
+ // std::unique_ptr<int> supports only move semantics:
+ QFutureInterface<UniquePtr> moveIface;
+ moveIface.reportStarted();
+
+ // std::vector<int> supports both copy and move:
+ QFutureInterface<std::vector<int>> copyIface;
+ copyIface.reportStarted();
+
+ const int expectedCount = 10;
+
+ for (int i = 0; i < expectedCount; ++i) {
+ moveIface.reportAndMoveResult(UniquePtr{new int(0b101010)}, i);
+ copyIface.reportAndMoveResult(std::vector<int>{1,2,3,4,5}, i);
+ }
+
+ moveIface.reportFinished();
+ copyIface.reportFinished();
+
+ testTakeResults(moveIface.future(), size_type(expectedCount));
+ if (QTest::currentTestFailed())
+ return;
+
+ testTakeResults(copyIface.future(), size_type(expectedCount));
+}
+
+void tst_QFuture::takeResult()
+{
+ QFutureInterface<UniquePtr> iface;
+ iface.reportStarted();
+ iface.reportAndMoveResult(UniquePtr{new int(0b101010)}, 0);
+ iface.reportFinished();
+
+ auto future = iface.future();
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isValid());
+ QCOMPARE(future.resultCount(), 1);
+
+ auto result = future.takeResult();
+ testFutureTaken(future);
+ if (QTest::currentTestFailed())
+ return;
+ testSingleResult(result);
+}
+
+void tst_QFuture::runAndTake()
+{
+ // Test if a 'moving' future can be used by
+ // QtConcurrent::run.
+
+ auto rabbit = [](){
+ // Let's wait a bit to give the test below some time
+ // to sync up with us with its watcher.
+ QThread::currentThread()->msleep(100);
+ return UniquePtr(new int(10));
+ };
+
+ QTestEventLoop loop;
+ QFutureWatcher<UniquePtr> watcha;
+ connect(&watcha, &QFutureWatcher<UniquePtr>::finished, [&loop](){
+ loop.exitLoop();
+ });
+
+ auto gotcha = QtConcurrent::run(rabbit);
+ watcha.setFuture(gotcha);
+
+ loop.enterLoopMSecs(500);
+ if (loop.timeout())
+ QSKIP("Failed to run the task, nothing to test");
+
+ gotcha = watcha.future();
+ testTakeResults(gotcha, size_type(1));
+}
+
+void tst_QFuture::resultsReadyAt_data()
+{
+ QTest::addColumn<bool>("testMove");
+
+ QTest::addRow("reportResult") << false;
+ QTest::addRow("reportAndMoveResult") << true;
+}
+
+void tst_QFuture::resultsReadyAt()
+{
+ QFETCH(const bool, testMove);
+
+ QFutureInterface<int> iface;
+ QFutureWatcher<int> watcher;
+ watcher.setFuture(iface.future());
+
+ QTestEventLoop eventProcessor;
+ connect(&watcher, &QFutureWatcher<int>::finished, &eventProcessor, &QTestEventLoop::exitLoop);
+
+ const int nExpectedResults = 4;
+ int reported = 0;
+ int taken = 0;
+ connect(&watcher, &QFutureWatcher<int>::resultsReadyAt,
+ [&iface, &reported, &taken](int begin, int end)
+ {
+ auto future = iface.future();
+ QVERIFY(end - begin > 0);
+ for (int i = begin; i < end; ++i, ++reported) {
+ QVERIFY(future.isResultReadyAt(i));
+ taken |= 1 << i;
+ }
+ });
+
+ auto report = [&iface, testMove](int index)
+ {
+ int dummyResult = 0b101010;
+ if (testMove)
+ iface.reportAndMoveResult(std::move(dummyResult), index);
+ else
+ iface.reportResult(&dummyResult, index);
+ };
+
+ const QSignalSpy readyCounter(&watcher, &QFutureWatcher<int>::resultsReadyAt);
+ QTimer::singleShot(0, [&iface, &report]{
+ // With filter mode == true, the result may go into the pending results.
+ // Reporting it as ready will allow an application to try and access the
+ // result, crashing on invalid (store.end()) iterator dereferenced.
+ iface.setFilterMode(true);
+ iface.reportStarted();
+ report(0);
+ report(1);
+ // This one - should not be reported (it goes into pending):
+ report(3);
+ // Let's close the 'gap' and make them all ready:
+ report(-1);
+ iface.reportFinished();
+ });
+
+ // Run event loop, QCoreApplication::postEvent is in use
+ // in QFutureInterface:
+ eventProcessor.enterLoopMSecs(2000);
+ QVERIFY(!eventProcessor.timeout());
+ if (QTest::currentTestFailed()) // Failed in our lambda observing 'ready at'
+ return;
+
+ QCOMPARE(reported, nExpectedResults);
+ QCOMPARE(nExpectedResults, iface.future().resultCount());
+ QCOMPARE(readyCounter.count(), 3);
+ QCOMPARE(taken, 0b1111);
+}
+
QTEST_MAIN(tst_QFuture)
#include "tst_qfuture.moc"
diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt
new file mode 100644
index 0000000000..54e3eb861d
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qfuturesynchronizer.pro.
+
+#####################################################################
+## tst_qfuturesynchronizer Test:
+#####################################################################
+
+add_qt_test(tst_qfuturesynchronizer
+ SOURCES
+ tst_qfuturesynchronizer.cpp
+)
diff --git a/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt
new file mode 100644
index 0000000000..c27412daac
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Generated from qfuturewatcher.pro.
+
+#####################################################################
+## tst_qfuturewatcher Test:
+#####################################################################
+
+add_qt_test(tst_qfuturewatcher
+ SOURCES
+ tst_qfuturewatcher.cpp
+ PUBLIC_LIBRARIES
+ Qt::Concurrent
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qmutex/CMakeLists.txt b/tests/auto/corelib/thread/qmutex/CMakeLists.txt
new file mode 100644
index 0000000000..536802f127
--- /dev/null
+++ b/tests/auto/corelib/thread/qmutex/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Generated from qmutex.pro.
+
+#####################################################################
+## tst_qmutex Test:
+#####################################################################
+
+add_qt_test(tst_qmutex
+ SOURCES
+ tst_qmutex.cpp
+)
+
+## Scopes:
+#####################################################################
+
+extend_target(tst_qmutex CONDITION WIN32
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt
new file mode 100644
index 0000000000..a07548a494
--- /dev/null
+++ b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qmutexlocker.pro.
+
+#####################################################################
+## tst_qmutexlocker Test:
+#####################################################################
+
+add_qt_test(tst_qmutexlocker
+ SOURCES
+ tst_qmutexlocker.cpp
+)
diff --git a/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt
new file mode 100644
index 0000000000..c52bc24491
--- /dev/null
+++ b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qreadlocker.pro.
+
+#####################################################################
+## tst_qreadlocker Test:
+#####################################################################
+
+add_qt_test(tst_qreadlocker
+ SOURCES
+ tst_qreadlocker.cpp
+)
diff --git a/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt
new file mode 100644
index 0000000000..3de89adb2d
--- /dev/null
+++ b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qreadwritelock.pro.
+
+#####################################################################
+## tst_qreadwritelock Test:
+#####################################################################
+
+add_qt_test(tst_qreadwritelock
+ SOURCES
+ tst_qreadwritelock.cpp
+)
diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt
new file mode 100644
index 0000000000..f630bdc43b
--- /dev/null
+++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Generated from qresultstore.pro.
+
+#####################################################################
+## tst_qresultstore Test:
+#####################################################################
+
+add_qt_test(tst_qresultstore
+ SOURCES
+ tst_qresultstore.cpp
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qresultstore/qresultstore.pro b/tests/auto/corelib/thread/qresultstore/qresultstore.pro
index bbebe0976b..80e79b1c1a 100644
--- a/tests/auto/corelib/thread/qresultstore/qresultstore.pro
+++ b/tests/auto/corelib/thread/qresultstore/qresultstore.pro
@@ -2,4 +2,3 @@ CONFIG += testcase
TARGET = tst_qresultstore
QT = core-private testlib
SOURCES = tst_qresultstore.cpp
-DEFINES += QT_STRICT_ITERATORS
diff --git a/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt
new file mode 100644
index 0000000000..3aaa71423e
--- /dev/null
+++ b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qsemaphore.pro.
+
+#####################################################################
+## tst_qsemaphore Test:
+#####################################################################
+
+add_qt_test(tst_qsemaphore
+ SOURCES
+ tst_qsemaphore.cpp
+)
diff --git a/tests/auto/corelib/thread/qthread/.prev_CMakeLists.txt b/tests/auto/corelib/thread/qthread/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..749a5e9734
--- /dev/null
+++ b/tests/auto/corelib/thread/qthread/.prev_CMakeLists.txt
@@ -0,0 +1,16 @@
+# Generated from qthread.pro.
+
+#####################################################################
+## tst_qthread Test:
+#####################################################################
+
+add_qt_test(tst_qthread
+ SOURCES
+ ../../../../shared/emulationdetector.h
+ tst_qthread.cpp
+ INCLUDE_DIRECTORIES
+ ../../../../shared
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/thread/qthread/CMakeLists.txt b/tests/auto/corelib/thread/qthread/CMakeLists.txt
new file mode 100644
index 0000000000..a21e239c35
--- /dev/null
+++ b/tests/auto/corelib/thread/qthread/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Generated from qthread.pro.
+
+#####################################################################
+## tst_qthread Test:
+#####################################################################
+
+add_qt_test(tst_qthread
+ SOURCES
+ ../../../../shared/emulationdetector.h
+ tst_qthread.cpp
+ INCLUDE_DIRECTORIES
+ ../../../../shared
+ LIBRARIES # special case
+ Threads::Threads # special case
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt
new file mode 100644
index 0000000000..c29b4e640a
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Generated from qthreadonce.pro.
+
+#####################################################################
+## tst_qthreadonce Test:
+#####################################################################
+
+add_qt_test(tst_qthreadonce
+ SOURCES
+ qthreadonce.cpp
+ tst_qthreadonce.cpp
+)
diff --git a/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt
new file mode 100644
index 0000000000..bc3fca1b6a
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qthreadpool.pro.
+
+#####################################################################
+## tst_qthreadpool Test:
+#####################################################################
+
+add_qt_test(tst_qthreadpool
+ SOURCES
+ tst_qthreadpool.cpp
+)
diff --git a/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt
new file mode 100644
index 0000000000..52a928863c
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt
@@ -0,0 +1,21 @@
+# special case skip regeneration
+# Generated from qthreadstorage.pro.
+
+#####################################################################
+## tst_qthreadstorage Test:
+#####################################################################
+
+add_qt_test(tst_qthreadstorage
+ SOURCES
+ tst_qthreadstorage.cpp
+ LIBRARIES # special case
+ Threads::Threads # special case
+
+)
+
+## Scopes:
+#####################################################################
+
+if(NOT ANDROID AND NOT WINRT)
+ add_subdirectory(crashonexit)
+endif()
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/.prev_CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/crashonexit/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..87ae29a04c
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/.prev_CMakeLists.txt
@@ -0,0 +1,15 @@
+# Generated from crashonexit.pro.
+
+#####################################################################
+## crashonexit Binary:
+#####################################################################
+
+add_qt_executable(crashonexit
+ OUTPUT_DIRECTORY "${INSTALL_TESTSDIR}/tst_qthreadstorage/crashonexit"
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qthreadstorage/crashonexit"
+ SOURCES
+ crashOnExit.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt
new file mode 100644
index 0000000000..b2bac9713a
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Generated from crashonexit.pro.
+
+#####################################################################
+## crashonexit Binary:
+#####################################################################
+
+add_qt_executable(crashOnExit_helper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." # special case
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qthreadstorage/crashOnExit_helper" # special case
+ SOURCES
+ crashOnExit.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt
new file mode 100644
index 0000000000..76f8b33aa4
--- /dev/null
+++ b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qwaitcondition.pro.
+
+#####################################################################
+## tst_qwaitcondition Test:
+#####################################################################
+
+add_qt_test(tst_qwaitcondition
+ SOURCES
+ tst_qwaitcondition.cpp
+)
diff --git a/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt
new file mode 100644
index 0000000000..00a9809174
--- /dev/null
+++ b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Generated from qwritelocker.pro.
+
+#####################################################################
+## tst_qwritelocker Test:
+#####################################################################
+
+add_qt_test(tst_qwritelocker
+ SOURCES
+ tst_qwritelocker.cpp
+)