diff options
Diffstat (limited to 'tests/auto/corelib/thread')
59 files changed, 726 insertions, 302 deletions
diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt index c1c00fe84d..d25d0205f5 100644 --- a/tests/auto/corelib/thread/CMakeLists.txt +++ b/tests/auto/corelib/thread/CMakeLists.txt @@ -1,15 +1,36 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -if(QT_FEATURE_thread) +if(QT_BUILD_WASM_BATCHED_TESTS) # not all tests currently work in WebAssembly add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) + add_subdirectory(qfuturesynchronizer) + add_subdirectory(qmutexlocker) + add_subdirectory(qreadlocker) add_subdirectory(qresultstore) - if(QT_FEATURE_concurrent AND NOT INTEGRITY) - add_subdirectory(qfuture) + add_subdirectory(qwritelocker) + return() +endif() + +if(QT_FEATURE_thread) + add_subdirectory(qatomicint) + add_subdirectory(qatomicinteger) + add_subdirectory(qatomicpointer) + if(QT_FEATURE_future) + if(QT_FEATURE_concurrent AND NOT INTEGRITY) + add_subdirectory(qfuture) + endif() + add_subdirectory(qresultstore) + add_subdirectory(qfuturesynchronizer) + if(NOT INTEGRITY) + add_subdirectory(qpromise) + endif() + # QTBUG-87431 + if(TARGET Qt::Concurrent AND NOT INTEGRITY) + add_subdirectory(qfuturewatcher) + endif() endif() - add_subdirectory(qfuturesynchronizer) add_subdirectory(qmutex) add_subdirectory(qmutexlocker) add_subdirectory(qreadlocker) @@ -24,12 +45,5 @@ if(QT_FEATURE_thread) add_subdirectory(qthreadstorage) add_subdirectory(qwaitcondition) add_subdirectory(qwritelocker) - if(NOT INTEGRITY) - add_subdirectory(qpromise) - endif() endif() -# QTBUG-87431 -if(TARGET Qt::Concurrent AND NOT INTEGRITY) - add_subdirectory(qfuturewatcher) -endif() diff --git a/tests/auto/corelib/thread/qatomicint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt index 6b79dc0177..239f3cce87 100644 --- a/tests/auto/corelib/thread/qatomicint/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicint Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicint LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_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 e8606b2568..63cb494c11 100644 --- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt index 71523bab24..882a9298f6 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_char Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_char LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_char SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt index 7fa5a2bbc8..8e53b59689 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_char16_t Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_char16_t LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_char16_t SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt index a98497d23e..5881d475f4 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_char32_t Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_char32_t LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_char32_t SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt index df134396fa..0915e77a8d 100644 --- a/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_int Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_int LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_int SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt index effe996f57..adf6638bfa 100644 --- a/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_long Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_long LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_long SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt index fb52b0de08..2ec977d7cb 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_qlonglong Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_qlonglong LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_qlonglong SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt index 04e688e9f0..a2450931d5 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_qptrdiff Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_qptrdiff LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_qptrdiff SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt index 6a45a850d5..98302b5d07 100644 --- a/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_quintptr Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_quintptr LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_quintptr SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt index 983d48c257..13acfc3e2b 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_qulonglong Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_qulonglong LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_qulonglong SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt index 146db43933..127f752cc2 100644 --- a/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_schar Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_schar LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_schar SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt index b7b7b9f1ad..df9d2af4c3 100644 --- a/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_short Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_short LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_short SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp index 9d7a71e7e7..d1a8a8f729 100644 --- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp +++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp @@ -1,29 +1,5 @@ // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#ifdef QT_ATOMIC_FORCE_CXX11 -// We need to check if this compiler has C++11 atomics and constexpr support. -// We can't rely on qcompilerdetection.h because it forces all of qglobal.h to -// be included, which causes qbasicatomic.h to be included too. -// Incomplete, but ok -# if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1500 && (__cplusplus >= 201103L || defined(__INTEL_CXX11_MODE__)) -# elif defined(__clang__) && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) -# if !__has_feature(cxx_constexpr) || !__has_feature(cxx_atomic) || !__has_include(<atomic>) -# undef QT_ATOMIC_FORCE_CXX11 -# endif -# elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) -# elif defined(_MSC_VER) - // We need MSVC 2015 because of: atomics (2012), constexpr (2015), and unrestricted unions (2015). - // Support for constexpr is not working completely on MSVC 2015 but it's enough for the test. -# else -# undef QT_ATOMIC_FORCE_CXX11 -# endif - -# ifndef QT_ATOMIC_FORCE_CXX11 -# undef QATOMIC_TEST_TYPE -# define QATOMIC_TEST_TYPE unsupported -# endif -#endif +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QAtomicInt> @@ -88,6 +64,7 @@ typedef signed char schar; typedef TEST_TYPE Type; typedef Type T; // shorthand +using U = std::make_unsigned_t<T>; enum { TypeIsUnsigned = Type(-1) > Type(0), TypeIsSigned = !TypeIsUnsigned @@ -98,6 +75,8 @@ template <> struct LargeIntTemplate<true> { typedef quint64 Type; }; template <> struct LargeIntTemplate<false> { typedef qint64 Type; }; typedef LargeIntTemplate<TypeIsUnsigned>::Type LargeInt; +namespace { + class tst_QAtomicIntegerXX : public QObject { Q_OBJECT @@ -313,46 +292,32 @@ void tst_QAtomicIntegerXX::loadAcquireStoreRelease() void tst_QAtomicIntegerXX::refDeref() { QFETCH(LargeInt, value); - const bool needToPreventOverflow = TypeIsSigned && value == std::numeric_limits<T>::max(); - const bool needToPreventUnderflow = TypeIsSigned && value == std::numeric_limits<T>::min(); - T nextValue = T(value); - if (!needToPreventOverflow) - ++nextValue; - T prevValue = T(value); - if (!needToPreventUnderflow) - --prevValue; + + // We perform arithmetic using the unsigned type U to avoid signed + // integer overflows in the non-atomic portion (atomics have well-defined, + // two's complement overflow, even signed ones). + T nextValue = T(U(value) + 1); + T prevValue = T(U(value) - 1); QAtomicInteger<T> atomic(value); - if (!needToPreventOverflow) { QCOMPARE(atomic.ref(), (nextValue != 0)); QCOMPARE(atomic.loadRelaxed(), nextValue); QCOMPARE(atomic.deref(), (value != 0)); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.deref(), (prevValue != 0)); QCOMPARE(atomic.loadRelaxed(), prevValue); QCOMPARE(atomic.ref(), (value != 0)); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(++atomic, nextValue); QCOMPARE(--atomic, T(value)); - } - if (!needToPreventUnderflow) { QCOMPARE(--atomic, prevValue); QCOMPARE(++atomic, T(value)); - } - if (!needToPreventOverflow) { QCOMPARE(atomic++, T(value)); QCOMPARE(atomic--, nextValue); - } - if (!needToPreventUnderflow) { QCOMPARE(atomic--, T(value)); QCOMPARE(atomic++, prevValue); - } QCOMPARE(atomic.loadRelaxed(), T(value)); } @@ -455,80 +420,55 @@ void tst_QAtomicIntegerXX::fetchAndAdd() QFETCH(LargeInt, value); QAtomicInteger<T> atomic(value); + // We perform the additions using the unsigned type U to avoid signed + // integer overflows in the non-atomic portion (atomics have well-defined, + // two's complement overflow, even signed ones). T parcel1 = 42; T parcel2 = T(0-parcel1); + T newValue1 = T(U(value) + parcel1); + T newValue2 = T(U(value) + parcel2); - const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() + parcel2; - const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() + parcel1; - - T newValue1 = T(value); - if (!needToPreventOverflow) - newValue1 += parcel1; - T newValue2 = T(value); - if (!needToPreventUnderflow) - newValue2 += parcel2; - - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue1); QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue2); QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue1); QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue2); QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2); - } QCOMPARE(atomic.loadAcquire(), T(value)); // operator+= - if (!needToPreventOverflow) { QCOMPARE(atomic += parcel1, newValue1); QCOMPARE(atomic += parcel2, T(value)); - } - if (!needToPreventUnderflow) { QCOMPARE(atomic += parcel2, newValue2); QCOMPARE(atomic += parcel1, T(value)); - } } void tst_QAtomicIntegerXX::fetchAndSub() @@ -536,80 +476,55 @@ void tst_QAtomicIntegerXX::fetchAndSub() QFETCH(LargeInt, value); QAtomicInteger<T> atomic(value); + // We perform the subtractions using the unsigned type U to avoid signed + // integer underrflows in the non-atomic portion (atomics have well-defined, + // two's complement underflow, even signed ones). T parcel1 = 42; T parcel2 = T(0-parcel1); + T newValue1 = T(U(value) - parcel1); + T newValue2 = T(U(value) - parcel2); - const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() - parcel1; - const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() - parcel2; - - T newValue1 = T(value); - if (!needToPreventUnderflow) - newValue1 -= parcel1; - T newValue2 = T(value); - if (!needToPreventOverflow) - newValue2 -= parcel2; - - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue1); QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue1); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue2); QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue2); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue1); QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue1); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value)); QCOMPARE(atomic.loadRelaxed(), newValue2); QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue2); - } QCOMPARE(atomic.loadRelaxed(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue1); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue2); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventUnderflow) { QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value)); QCOMPARE(atomic.loadAcquire(), newValue1); QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue1); - } QCOMPARE(atomic.loadAcquire(), T(value)); - if (!needToPreventOverflow) { QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value)); QCOMPARE(atomic.loadAcquire(), newValue2); QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue2); - } QCOMPARE(atomic.loadAcquire(), T(value)); // operator-= - if (!needToPreventUnderflow) { QCOMPARE(atomic -= parcel1, newValue1); QCOMPARE(atomic -= parcel2, T(value)); - } - if (!needToPreventOverflow) { QCOMPARE(atomic -= parcel2, newValue2); QCOMPARE(atomic -= parcel1, T(value)); - } } void tst_QAtomicIntegerXX::fetchAndOr() @@ -759,8 +674,9 @@ void tst_QAtomicIntegerXX::fetchAndXor() QCOMPARE(atomic ^= minusOne, T(~value)); QCOMPARE(atomic ^= minusOne, T(value)); } - -#include "tst_qatomicinteger.moc" +} QTEST_APPLESS_MAIN(tst_QAtomicIntegerXX) +#include "tst_qatomicinteger.moc" + diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt index 9385b64622..95d88d31a6 100644 --- a/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_uchar Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_uchar LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_uchar SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt index 3c434697c1..2ab977ef6a 100644 --- a/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_uint Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_uint LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_uint SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt index c757898291..7707bd53b5 100644 --- a/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_ulong Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_ulong LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_ulong SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt index e77b01ee6e..667e9eade6 100644 --- a/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_ushort Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_ushort LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_ushort SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt index 499d301f7d..0e2d084b58 100644 --- a/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicinteger_wchar_t Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicinteger_wchar_t LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qatomicinteger_wchar_t SOURCES ../tst_qatomicinteger.cpp diff --git a/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt index 82f6817bf1..cd8df9db66 100644 --- a/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt +++ b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qatomicpointer Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicpointer LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_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 c6bd784270..347831819e 100644 --- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt index d0ef0762fd..ba5730d5cf 100644 --- a/tests/auto/corelib/thread/qfuture/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt @@ -5,11 +5,18 @@ ## tst_qfuture Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfuture LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfuture SOURCES tst_qfuture.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) qt_internal_extend_target(tst_qfuture CONDITION MSVC diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 79ca38209e..4cb29c514a 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -1,5 +1,8 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses + #define QFUTURE_TEST #include <QCoreApplication> @@ -14,6 +17,7 @@ #include <private/qobject_p.h> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qfuture.h> #include <qfuturewatcher.h> #include <qresultstore.h> @@ -158,6 +162,7 @@ class tst_QFuture: public QObject { Q_OBJECT private slots: + void compareCompiles(); void resultStore(); void future(); void futureToVoid(); @@ -201,6 +206,7 @@ private slots: #endif void onCanceled(); void cancelContinuations(); + void continuationsWithContext_data(); void continuationsWithContext(); void continuationsWithMoveOnlyLambda(); #if 0 @@ -269,6 +275,12 @@ private: QtPrivate::ResultStoreBase &store; }; +void tst_QFuture::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QFuture<int>::const_iterator>(); + QTestPrivate::testEqualityOperatorsCompile<QFuture<QString>::const_iterator>(); +} + void tst_QFuture::resultStore() { int int0 = 0; @@ -1355,16 +1367,16 @@ void tst_QFuture::iterators() QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1; - QCOMPARE(i1, i1); - QCOMPARE(i1, c1); - QCOMPARE(c1, i1); - QCOMPARE(c1, c1); - QCOMPARE(i2, i2); - QCOMPARE(i2, c2); - QCOMPARE(c2, i2); - QCOMPARE(c2, c2); - QCOMPARE(1 + i1, i1 + 1); - QCOMPARE(1 + c1, c1 + 1); + QT_TEST_EQUALITY_OPS(i1, i1, true); + QT_TEST_EQUALITY_OPS(i1, c1, true); + QT_TEST_EQUALITY_OPS(c1, i1, true); + QT_TEST_EQUALITY_OPS(c1, c1, true); + QT_TEST_EQUALITY_OPS(i2, i2, true); + QT_TEST_EQUALITY_OPS(i2, c2, true); + QT_TEST_EQUALITY_OPS(c2, i2, true); + QT_TEST_EQUALITY_OPS(c2, c2, true); + QT_TEST_EQUALITY_OPS(1 + i1, i1 + 1, true); + QT_TEST_EQUALITY_OPS(1 + c1, c1 + 1, true); QVERIFY(i1 != i2); QVERIFY(i1 != c2); @@ -3220,15 +3232,35 @@ void tst_QFuture::cancelContinuations() } } +void tst_QFuture::continuationsWithContext_data() +{ + QTest::addColumn<bool>("inOtherThread"); + QTest::addRow("in-other-thread") << true; + QTest::addRow("in-main-thread-qtbug119406") << false; +} + void tst_QFuture::continuationsWithContext() { - QThread thread; - thread.start(); + QFETCH(bool, inOtherThread); + auto tstThread = QThread::currentThread(); + QThread *thread = inOtherThread ? new QThread + : tstThread; auto context = new QObject(); - context->moveToThread(&thread); - auto tstThread = QThread::currentThread(); + const auto cleanupGuard = qScopeGuard([&] { + context->deleteLater(); + if (thread != tstThread) { + thread->quit(); + thread->wait(); + delete thread; + } + }); + + if (inOtherThread) { + thread->start(); + context->moveToThread(thread); + } // .then() { @@ -3241,12 +3273,12 @@ void tst_QFuture::continuationsWithContext() }) .then(context, [&](int val) { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return val + 1; }) .then([&](int val) { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return val + 1; }); @@ -3262,12 +3294,12 @@ void tst_QFuture::continuationsWithContext() auto future = promise.future() .onCanceled(context, [&] { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return 1; }) .then([&](int val) { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return val + 1; }); @@ -3284,17 +3316,17 @@ void tst_QFuture::continuationsWithContext() // like QPointers to the parent not being set to nullptr during child // object destruction. QPointer shortLivedContext = new FakeQWidget(); - shortLivedContext->moveToThread(&thread); + shortLivedContext->moveToThread(thread); QPromise<int> promise; auto future = promise.future() .then(shortLivedContext, [&](int val) { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return val + 1000; }) .onCanceled([&, ptr=QPointer(shortLivedContext)] { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; if (ptr) return 1; @@ -3304,10 +3336,10 @@ void tst_QFuture::continuationsWithContext() QMetaObject::invokeMethod(shortLivedContext, [&]() { delete shortLivedContext; - }, Qt::BlockingQueuedConnection); + }, inOtherThread ? Qt::BlockingQueuedConnection + : Qt::DirectConnection); promise.finish(); - QCOMPARE(future.result(), 2); } @@ -3323,12 +3355,12 @@ void tst_QFuture::continuationsWithContext() }) .onFailed(context, [&] { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return 1; }) .then([&](int val) { - if (QThread::currentThread() != &thread) + if (QThread::currentThread() != thread) return 0; return val + 1; }); @@ -3337,11 +3369,6 @@ void tst_QFuture::continuationsWithContext() QCOMPARE(future.result(), 2); } #endif // QT_NO_EXCEPTIONS - - context->deleteLater(); - - thread.quit(); - thread.wait(); } void tst_QFuture::continuationsWithMoveOnlyLambda() @@ -3432,17 +3459,6 @@ 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.isSuspending(), false); - QCOMPARE(noMoreFuture.isSuspended(), false); -#if QT_DEPRECATED_SINCE(6, 0) -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - QCOMPARE(noMoreFuture.isPaused(), false); -QT_WARNING_POP -#endif - QCOMPARE(noMoreFuture.isFinished(), false); QCOMPARE(noMoreFuture.progressValue(), 0); } @@ -3861,8 +3877,6 @@ void tst_QFuture::signalConnect() QSignalSpy spy(sender, &QObject::destroyed); sender->deleteLater(); - // emit the signal when sender is being destroyed - QObject::connect(sender, &QObject::destroyed, [sender] { sender->emitIntArg(42); }); spy.wait(); QVERIFY(future.isCanceled()); @@ -3901,7 +3915,7 @@ void tst_QFuture::signalConnect() { SenderObject sender; -#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +#if defined(Q_CC_MSVC_ONLY) && (Q_CC_MSVC < 1940 || __cplusplus < 202002L) #define EXPECT_FUTURE_CONNECT_FAIL() QEXPECT_FAIL("", "QTBUG-101761, test fails on Windows/MSVC", Continue) #else QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in SenderObject"); @@ -3921,9 +3935,6 @@ void tst_QFuture::signalConnect() void tst_QFuture::waitForFinished() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else QFutureInterface<void> fi; auto future = fi.future(); @@ -3944,7 +3955,6 @@ void tst_QFuture::waitForFinished() QVERIFY(waitingThread->wait()); QVERIFY(waitingThread->isFinished()); -#endif } void tst_QFuture::rejectResultOverwrite_data() @@ -4557,7 +4567,7 @@ void tst_QFuture::whenAllIteratorsWithFailed() p1.finish(); QVERIFY(finished); #else - QSKIP("Exceptions are disabled, skipping the test") + QSKIP("Exceptions are disabled, skipping the test"); #endif } @@ -5025,6 +5035,40 @@ void tst_QFuture::continuationsDontLeak() QVERIFY(continuationIsRun); } QCOMPARE(InstanceCounter::count, 0); + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QtFuture::whenAll(f).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QList fs{f}; + QtFuture::whenAll(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QtFuture::whenAny(f).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QList fs{f}; + QtFuture::whenAny(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } } // This test checks that we do not get use-after-free diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt index f3a37cbc0b..c0f4561c51 100644 --- a/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qfuturesynchronizer Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfuturesynchronizer LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfuturesynchronizer SOURCES tst_qfuturesynchronizer.cpp diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp b/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp index fe84ec1ae4..62ad4f872a 100644 --- a/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp +++ b/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> @@ -13,6 +13,7 @@ class tst_QFutureSynchronizer : public QObject private Q_SLOTS: void construction(); + void setFutureAliasingExistingMember(); void addFuture(); void cancelOnWait(); void clearFutures(); @@ -33,6 +34,38 @@ void tst_QFutureSynchronizer::construction() QCOMPARE(synchronizerWithFuture.futures().size(), 1); } +void tst_QFutureSynchronizer::setFutureAliasingExistingMember() +{ + // + // GIVEN: a QFutureSynchronizer with one QFuture: + // + QFutureSynchronizer synchronizer(QtFuture::makeReadyValueFuture(42)); + + // + // WHEN: calling setFuture() with an alias of the QFuture already in `synchronizer`: + // + for (int i = 0; i < 2; ++i) { + // The next line triggers -Wdangling-reference, but it's a FP because + // of implicit sharing. We cannot keep a copy of synchronizer.futures() + // around to avoid the warning, as the extra copy would cause a detach() + // of m_futures inside setFuture() with the consequence that `f` no longer + // aliases an element in m_futures, which is the goal of this test. +QT_WARNING_PUSH +#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301 +QT_WARNING_DISABLE_GCC("-Wdangling-reference") +#endif + const auto &f = synchronizer.futures().constFirst(); +QT_WARNING_POP + synchronizer.setFuture(f); + } + + // + // THEN: it didn't crash + // + QCOMPARE(synchronizer.futures().size(), 1); + QCOMPARE(synchronizer.futures().constFirst().result(), 42); +} + void tst_QFutureSynchronizer::addFuture() { QFutureSynchronizer<void> synchronizer; diff --git a/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt index 8444575ee7..65417199a3 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qfuturewatcher Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfuturewatcher LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qfuturewatcher SOURCES tst_qfuturewatcher.cpp diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index 62a9ab40e7..40aa89ded4 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QCoreApplication> #include <QDebug> #include <QElapsedTimer> @@ -26,6 +26,7 @@ private slots: void cancelAndFinish(); void resultAt(); void resultReadyAt(); + void orderedResultReadyAt(); void futureSignals(); void watchFinishedFuture(); void watchCanceledFuture(); @@ -280,6 +281,28 @@ void tst_QFutureWatcher::resultReadyAt() QVERIFY(resultSpy.wait()); } +void tst_QFutureWatcher::orderedResultReadyAt() +{ + for (int i = 0; i < 1000; ++i) { + QObject context; + QFuture<QString> f = run([](QPromise<QString> &fi) { + fi.addResult("First"); + fi.addResult("Second"); + }); + QList<int> actualIndices; + + QFutureWatcher<QString> watcher; + connect(&watcher, &QFutureWatcherBase::resultReadyAt, &context, + [&actualIndices](int index) { actualIndices.append(index); }); + watcher.setFuture(f); + f.waitForFinished(); + QCoreApplication::processEvents(); + const QList<int> expectedIndices{0, 1}; + QCOMPARE(actualIndices.size(), expectedIndices.size()); + QCOMPARE(actualIndices, expectedIndices); + } +} + class SignalSlotObject : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/thread/qmutex/CMakeLists.txt b/tests/auto/corelib/thread/qmutex/CMakeLists.txt index b0d80213a5..5a92a2bffd 100644 --- a/tests/auto/corelib/thread/qmutex/CMakeLists.txt +++ b/tests/auto/corelib/thread/qmutex/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qmutex Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qmutex LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qmutex SOURCES tst_qmutex.cpp diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp index d2c0a38fd0..4753444ab9 100644 --- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSemaphore> @@ -61,6 +61,8 @@ static QSemaphore threadsTurn; enum { #ifdef Q_OS_WIN systemTimersResolution = 16, +#elif defined(Q_OS_QNX) + systemTimersResolution = 10, #else systemTimersResolution = 1, #endif @@ -97,19 +99,19 @@ void tst_QMutex::tryLock_non_recursive() QElapsedTimer timer; timer.start(); QVERIFY(!normalMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); testsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution); + QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); timer.start(); // it's non-recursive, so the following lock needs to fail QVERIFY(!normalMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); @@ -123,7 +125,7 @@ void tst_QMutex::tryLock_non_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(0)); - QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.tryLock(0)); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); @@ -134,7 +136,7 @@ void tst_QMutex::tryLock_non_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(3000)); - QVERIFY(timer.elapsed() < 3000 + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), 3000 + systemTimersResolution); normalMutex.unlock(); testsTurn.release(); @@ -145,43 +147,43 @@ void tst_QMutex::tryLock_non_recursive() Thread thread; thread.start(); - // TEST 1: thread can't acquire lock + qDebug("TEST 1: thread can't acquire lock"); testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); - // TEST 2: thread can acquire lock + qDebug("TEST 2: thread can acquire lock"); testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); - // TEST 3: thread can't acquire lock, timeout = waitTime + qDebug("TEST 3: thread can't acquire lock, timeout = waitTime"); testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); - // TEST 4: thread can acquire lock, timeout = waitTime + qDebug("TEST 4: thread can acquire lock, timeout = waitTime"); testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); - // TEST 5: thread can't acquire lock, timeout = 0 + qDebug("TEST 5: thread can't acquire lock, timeout = 0"); testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); - // TEST 6: thread can acquire lock, timeout = 0 + qDebug("TEST 6: thread can acquire lock, timeout = 0"); testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); - // TEST 7: thread can acquire lock, timeout = 3000 (QTBUG-24795) + qDebug("TEST 7: thread can acquire lock, timeout = 3000 (QTBUG-24795)"); testsTurn.acquire(); normalMutex.lock(); threadsTurn.release(); @@ -222,19 +224,19 @@ void tst_QMutex::try_lock_for_non_recursive() QElapsedTimer timer; timer.start(); QVERIFY(!normalMutex.try_lock_for(waitTimeAsDuration)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); testsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.try_lock_for(waitTimeAsDuration)); - QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution); + QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); timer.start(); // it's non-recursive, so the following lock needs to fail QVERIFY(!normalMutex.try_lock_for(waitTimeAsDuration)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); @@ -248,7 +250,7 @@ void tst_QMutex::try_lock_for_non_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds::zero())); - QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.try_lock_for(std::chrono::milliseconds::zero())); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); @@ -259,7 +261,7 @@ void tst_QMutex::try_lock_for_non_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds(3000))); - QVERIFY(timer.elapsed() < 3000 + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), 3000 + systemTimersResolution); normalMutex.unlock(); testsTurn.release(); @@ -347,19 +349,19 @@ void tst_QMutex::try_lock_until_non_recursive() threadsTurn.acquire(); auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(!normalMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration); + QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration); testsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime threadsTurn.acquire(); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(normalMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration); + QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; // it's non-recursive, so the following lock needs to fail QVERIFY(!normalMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration); + QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); @@ -373,7 +375,7 @@ void tst_QMutex::try_lock_until_non_recursive() threadsTurn.acquire(); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(normalMutex.try_lock_until(std::chrono::steady_clock::now())); - QVERIFY(std::chrono::steady_clock::now() < endTimePoint + systemTimersResolutionAsDuration); + QCOMPARE_LT(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.try_lock_until(std::chrono::steady_clock::now())); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); @@ -384,7 +386,7 @@ void tst_QMutex::try_lock_until_non_recursive() threadsTurn.acquire(); endTimePoint = std::chrono::steady_clock::now() + std::chrono::milliseconds(3000); QVERIFY(normalMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() < endTimePoint + systemTimersResolutionAsDuration); + QCOMPARE_LT(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration); normalMutex.unlock(); testsTurn.release(); @@ -472,14 +474,14 @@ void tst_QMutex::tryLock_recursive() QElapsedTimer timer; timer.start(); QVERIFY(!recursiveMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); QVERIFY(!recursiveMutex.tryLock(0)); testsTurn.release(); threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution); + QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.tryLock(waitTime)); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); @@ -497,7 +499,7 @@ void tst_QMutex::tryLock_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.tryLock(0)); - QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.tryLock(0)); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); @@ -596,14 +598,14 @@ void tst_QMutex::try_lock_for_recursive() QElapsedTimer timer; timer.start(); QVERIFY(!recursiveMutex.try_lock_for(waitTimeAsDuration)); - QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution); QVERIFY(!recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); testsTurn.release(); threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.try_lock_for(waitTimeAsDuration)); - QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution); + QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.try_lock_for(waitTimeAsDuration)); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); @@ -621,7 +623,7 @@ void tst_QMutex::try_lock_for_recursive() threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); - QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); @@ -720,14 +722,14 @@ void tst_QMutex::try_lock_until_recursive() threadsTurn.acquire(); auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(!recursiveMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration); + QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration); QVERIFY(!recursiveMutex.try_lock()); testsTurn.release(); threadsTurn.acquire(); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(recursiveMutex.try_lock_until(endTimePoint)); - QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration); + QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(recursiveMutex.try_lock_until(endTimePoint)); @@ -746,7 +748,7 @@ void tst_QMutex::try_lock_until_recursive() threadsTurn.acquire(); endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; QVERIFY(recursiveMutex.try_lock_until(std::chrono::steady_clock::now())); - QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration); + QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.try_lock_until(std::chrono::steady_clock::now())); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); diff --git a/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt index 8647a4a607..7b2d6dc1c2 100644 --- a/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt +++ b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qmutexlocker Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qmutexlocker LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qmutexlocker SOURCES tst_qmutexlocker.cpp diff --git a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp index 6227d62641..6ccab04c27 100644 --- a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp +++ b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qpromise/CMakeLists.txt b/tests/auto/corelib/thread/qpromise/CMakeLists.txt index 772721a55c..c1ca30b34a 100644 --- a/tests/auto/corelib/thread/qpromise/CMakeLists.txt +++ b/tests/auto/corelib/thread/qpromise/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qpromise Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qpromise LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qpromise SOURCES tst_qpromise.cpp diff --git a/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp index a1c7da280e..2cef0dca95 100644 --- a/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp +++ b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // Note: this file is published under a license that is different from a default // test sources license. This is intentional to comply with default diff --git a/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp index 0b0e6c321f..2c12e41c93 100644 --- a/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp +++ b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QCoreApplication> #include <QDebug> @@ -44,6 +44,8 @@ private slots: void cancelWhenReassigned(); void cancelWhenDestroyedWithoutStarting(); void cancelWhenDestroyedRunsContinuations(); + void cancelWhenDestroyedWithFailureHandler(); // QTBUG-114606 + void continuationsRunWhenFinished(); void finishWhenSwapped(); void cancelWhenMoved(); void waitUntilResumed(); @@ -290,6 +292,10 @@ void tst_QPromise::setException() std::make_exception_ptr(TestException())); RUN_TEST_FUNC(testExceptionCaught, QPromise<int>(), std::make_exception_ptr(TestException())); + RUN_TEST_FUNC(testExceptionCaught, QPromise<CopyOnlyType>(), + std::make_exception_ptr(TestException())); + RUN_TEST_FUNC(testExceptionCaught, QPromise<MoveOnlyType>(), + std::make_exception_ptr(TestException())); } #endif @@ -303,6 +309,8 @@ void tst_QPromise::cancel() testCancel(QPromise<void>()); testCancel(QPromise<int>()); + testCancel(QPromise<CopyOnlyType>()); + testCancel(QPromise<MoveOnlyType>()); } void tst_QPromise::progress() @@ -330,13 +338,13 @@ void tst_QPromise::progress() RUN_TEST_FUNC(testProgress, QPromise<void>()); RUN_TEST_FUNC(testProgress, QPromise<int>()); + RUN_TEST_FUNC(testProgress, QPromise<CopyOnlyType>()); + RUN_TEST_FUNC(testProgress, QPromise<MoveOnlyType>()); } void tst_QPromise::addInThread() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) const auto testAddResult = [] (auto promise, const auto &result) { promise.start(); auto f = promise.future(); @@ -357,9 +365,7 @@ void tst_QPromise::addInThread() void tst_QPromise::addInThreadMoveOnlyObject() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<MoveOnlyType> promise; promise.start(); auto f = promise.future(); @@ -376,9 +382,7 @@ void tst_QPromise::addInThreadMoveOnlyObject() void tst_QPromise::reportFromMultipleThreads() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<int> promise; auto f = promise.future(); promise.start(); @@ -402,9 +406,7 @@ void tst_QPromise::reportFromMultipleThreads() void tst_QPromise::reportFromMultipleThreadsByMovedPromise() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<int> initialPromise; auto f = initialPromise.future(); { @@ -436,9 +438,7 @@ void tst_QPromise::reportFromMultipleThreadsByMovedPromise() void tst_QPromise::doNotCancelWhenFinished() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) const auto testFinishedPromise = [] (auto promise) { auto f = promise.future(); promise.start(); @@ -455,15 +455,15 @@ void tst_QPromise::doNotCancelWhenFinished() RUN_TEST_FUNC(testFinishedPromise, QPromise<void>()); RUN_TEST_FUNC(testFinishedPromise, QPromise<int>()); RUN_TEST_FUNC(testFinishedPromise, QPromise<QString>()); + RUN_TEST_FUNC(testFinishedPromise, QPromise<CopyOnlyType>()); + RUN_TEST_FUNC(testFinishedPromise, QPromise<MoveOnlyType>()); #endif } #ifndef QT_NO_EXCEPTIONS void tst_QPromise::cancelWhenDestroyed() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<int> initialPromise; auto f = initialPromise.future(); @@ -497,9 +497,7 @@ void tst_QPromise::cancelWhenDestroyed() void tst_QPromise::cancelWhenReassigned() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<int> promise; auto f = promise.future(); promise.start(); @@ -516,11 +514,12 @@ void tst_QPromise::cancelWhenReassigned() #endif } -void tst_QPromise::cancelWhenDestroyedWithoutStarting() +template <typename T> +static inline void testCancelWhenDestroyedWithoutStarting() { - QFuture<void> future; + QFuture<T> future; { - QPromise<void> promise; + QPromise<T> promise; future = promise.future(); } future.waitForFinished(); @@ -529,17 +528,26 @@ void tst_QPromise::cancelWhenDestroyedWithoutStarting() QVERIFY(future.isFinished()); } -void tst_QPromise::cancelWhenDestroyedRunsContinuations() +void tst_QPromise::cancelWhenDestroyedWithoutStarting() { - QFuture<void> future; + testCancelWhenDestroyedWithoutStarting<void>(); + testCancelWhenDestroyedWithoutStarting<int>(); + testCancelWhenDestroyedWithoutStarting<CopyOnlyType>(); + testCancelWhenDestroyedWithoutStarting<MoveOnlyType>(); +} + +template <typename T> +static inline void testCancelWhenDestroyedRunsContinuations() +{ + QFuture<T> future; bool onCanceledCalled = false; bool thenCalled = false; { - QPromise<void> promise; + QPromise<T> promise; future = promise.future(); - future.then([&] { + future.then([&] (auto&&) { thenCalled = true; - }).onCanceled([&] { + }).onCanceled([&] () { onCanceledCalled = true; }); } @@ -548,11 +556,81 @@ void tst_QPromise::cancelWhenDestroyedRunsContinuations() QVERIFY(onCanceledCalled); } -void tst_QPromise::finishWhenSwapped() +void tst_QPromise::cancelWhenDestroyedRunsContinuations() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); + testCancelWhenDestroyedRunsContinuations<void>(); + testCancelWhenDestroyedRunsContinuations<int>(); + testCancelWhenDestroyedRunsContinuations<CopyOnlyType>(); + testCancelWhenDestroyedRunsContinuations<MoveOnlyType>(); +} + +template <typename T> +static inline void testCancelWhenDestroyedWithFailureHandler() +{ + QFuture<T> future; + bool onFailedCalled = false; + bool thenCalled = false; + { + QPromise<T> promise; + future = promise.future(); + future + .onFailed([&] () { + onFailedCalled = true; + if constexpr (!std::is_same_v<void, T>) + return T{}; + }) + .then([&] (auto&&) { + thenCalled = true; + }); + } + QVERIFY(future.isFinished()); + QVERIFY(!onFailedCalled); + QVERIFY(!thenCalled); +} + +void tst_QPromise::cancelWhenDestroyedWithFailureHandler() +{ +#ifndef QT_NO_EXCEPTIONS + testCancelWhenDestroyedWithFailureHandler<void>(); + testCancelWhenDestroyedWithFailureHandler<int>(); + testCancelWhenDestroyedWithFailureHandler<CopyOnlyType>(); + testCancelWhenDestroyedWithFailureHandler<MoveOnlyType>(); #else + QSKIP("Exceptions are disabled, skipping the test"); +#endif +} + +template <typename T> +static inline void testContinuationsRunWhenFinished() +{ + QPromise<T> promise; + QFuture<T> future = promise.future(); + + bool thenCalled = false; + future.then([&] (auto&&) { + thenCalled = true; + }); + + promise.start(); + if constexpr (!std::is_void_v<T>) { + promise.addResult(T{}); + } + promise.finish(); + + QVERIFY(thenCalled); +} + +void tst_QPromise::continuationsRunWhenFinished() +{ + testContinuationsRunWhenFinished<void>(); + testContinuationsRunWhenFinished<int>(); + testContinuationsRunWhenFinished<CopyOnlyType>(); + testContinuationsRunWhenFinished<MoveOnlyType>(); +} + +void tst_QPromise::finishWhenSwapped() +{ +#if QT_CONFIG(cxx11_future) QPromise<int> promise1; auto f1 = promise1.future(); promise1.start(); @@ -590,16 +668,15 @@ void tst_QPromise::finishWhenSwapped() #endif } -void tst_QPromise::cancelWhenMoved() +template <typename T> +void testCancelWhenMoved() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else - QPromise<int> promise1; +#if QT_CONFIG(cxx11_future) + QPromise<T> promise1; auto f1 = promise1.future(); promise1.start(); - QPromise<int> promise2; + QPromise<T> promise2; auto f2 = promise2.future(); promise2.start(); @@ -623,6 +700,14 @@ void tst_QPromise::cancelWhenMoved() #endif } +void tst_QPromise::cancelWhenMoved() +{ + testCancelWhenMoved<void>(); + testCancelWhenMoved<int>(); + testCancelWhenMoved<CopyOnlyType>(); + testCancelWhenMoved<MoveOnlyType>(); +} + void tst_QPromise::waitUntilResumed() { #if !QT_CONFIG(cxx11_future) @@ -654,9 +739,7 @@ void tst_QPromise::waitUntilResumed() void tst_QPromise::waitUntilCanceled() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else +#if QT_CONFIG(cxx11_future) QPromise<int> promise; promise.start(); auto f = promise.future(); diff --git a/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt index 3f8c206322..7e80a4df81 100644 --- a/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt +++ b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qreadlocker Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qreadlocker LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qreadlocker SOURCES tst_qreadlocker.cpp diff --git a/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp b/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp index 69cfc330b1..e21f80c05d 100644 --- a/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp +++ b/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt index 189a177bac..5ed3012e04 100644 --- a/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt +++ b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qreadwritelock Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qreadwritelock LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qreadwritelock SOURCES tst_qreadwritelock.cpp diff --git a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp index 12b2d3afb9..86dfa5faff 100644 --- a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSemaphore> diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt index f458694e7b..5abfc14ac6 100644 --- a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt +++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt @@ -5,9 +5,16 @@ ## tst_qresultstore Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qresultstore LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qresultstore SOURCES tst_qresultstore.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp index 902323a79c..722184a72a 100644 --- a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp +++ b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> - +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qresultstore.h> using namespace QtPrivate; @@ -23,6 +23,7 @@ class tst_QtConcurrentResultStore : public QObject public slots: void init(); private slots: + void compareCompiles(); void construction(); void iterators(); void addResult(); @@ -52,6 +53,11 @@ void tst_QtConcurrentResultStore::init() vec1 = QList<int> { 4, 5 }; } +void tst_QtConcurrentResultStore::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<ResultIteratorBase>(); +} + void tst_QtConcurrentResultStore::construction() { ResultStoreBase store; @@ -74,17 +80,20 @@ void tst_QtConcurrentResultStore::iterators() storebase.addResult(1, &int1); // ResultStoreBase does not take ownership, only ResultStore<> does. ResultIteratorBase it = storebase.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, storebase.begin()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), true); QVERIFY(it != storebase.end()); ++it; QCOMPARE(it.resultIndex(), 1); QVERIFY(it != storebase.begin()); QVERIFY(it != storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), false); + QT_TEST_EQUALITY_OPS(it, storebase.end(), false); ++it; QVERIFY(it != storebase.begin()); QCOMPARE(it, storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.end(), true); } } @@ -147,8 +156,8 @@ void tst_QtConcurrentResultStore::addResults() store.addResults(-1, &vec1); ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); @@ -162,7 +171,7 @@ void tst_QtConcurrentResultStore::addResults() QCOMPARE(it.resultIndex(), 3); ++it; - QCOMPARE(it, store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QList<int> empty; const auto countBefore = store.count(); @@ -184,22 +193,22 @@ void tst_QtConcurrentResultStore::resultIndex() ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QVERIFY(it == store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); - QVERIFY(it != store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), false); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 2); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 3); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; - QVERIFY(it == store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QCOMPARE(store.resultAt(0).value<int>(), int0); QCOMPARE(store.resultAt(1).value<int>(), vec0[0]); @@ -549,7 +558,7 @@ struct CountedObject const size_t previousLiveCount; }; - int id = 0; + size_t id = 0; static size_t liveCount; }; diff --git a/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt index 5e5f6cf512..9f8a87558a 100644 --- a/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt +++ b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qsemaphore Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qsemaphore LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qsemaphore SOURCES tst_qsemaphore.cpp diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index 21b37feef0..3bb1e1960c 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qthread/BLACKLIST b/tests/auto/corelib/thread/qthread/BLACKLIST index c683154da1..08e9912455 100644 --- a/tests/auto/corelib/thread/qthread/BLACKLIST +++ b/tests/auto/corelib/thread/qthread/BLACKLIST @@ -1,5 +1,3 @@ [wait3_slowDestructor] windows-10 -[sleep] -windows-7sp1 diff --git a/tests/auto/corelib/thread/qthread/CMakeLists.txt b/tests/auto/corelib/thread/qthread/CMakeLists.txt index 1e63d10bd1..abcea1ef9c 100644 --- a/tests/auto/corelib/thread/qthread/CMakeLists.txt +++ b/tests/auto/corelib/thread/qthread/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qthread Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qthread LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qthread SOURCES tst_qthread.cpp diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 511bc02b45..18c8d5fbd5 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QTestEventLoop> @@ -53,6 +53,7 @@ private slots: void setStackSize(); void exit(); void start(); + void startSlotUsedInStringBasedLookups(); void terminate(); void quit(); void started(); @@ -136,11 +137,13 @@ class Current_Thread : public QThread public: Qt::HANDLE id; QThread *thread; + bool runCalledInCurrentThread = false; void run() override { id = QThread::currentThreadId(); thread = QThread::currentThread(); + runCalledInCurrentThread = thread->isCurrentThread(); } }; @@ -275,6 +278,11 @@ void tst_QThread::currentThreadId() QVERIFY(thread.wait(five_minutes)); QVERIFY(thread.id != nullptr); QVERIFY(thread.id != QThread::currentThreadId()); + QVERIFY(!thread.isCurrentThread()); + QVERIFY(!thread.thread->isCurrentThread()); + QVERIFY(thread.QThread::thread()->isCurrentThread()); + QVERIFY(thread.runCalledInCurrentThread); + QVERIFY(qApp->thread()->isCurrentThread()); } void tst_QThread::currentThread() @@ -466,6 +474,56 @@ void tst_QThread::start() } } +class QThreadStarter : public QObject +{ + Q_OBJECT +public: + using QObject::QObject; +Q_SIGNALS: + void start(QThread::Priority); +}; + +class QThreadSelfStarter : public QThread +{ + Q_OBJECT +public: + using QThread::QThread; + + void check() + { + QVERIFY(connect(this, SIGNAL(starting(Priority)), + this, SLOT(start(Priority)))); + QVERIFY(QMetaObject::invokeMethod(this, "start", Q_ARG(Priority, IdlePriority))); + } + +Q_SIGNALS: + void starting(Priority); +}; + +void tst_QThread::startSlotUsedInStringBasedLookups() +{ + // QTBUG-124723 + + QThread thread; + { + QThreadStarter starter; + QVERIFY(QObject::connect(&starter, SIGNAL(start(QThread::Priority)), + &thread, SLOT(start(QThread::Priority)))); + } + { + QThreadSelfStarter selfStarter; + selfStarter.check(); + if (QTest::currentTestFailed()) + return; + selfStarter.exit(); + selfStarter.wait(30s); + } + QVERIFY(QMetaObject::invokeMethod(&thread, "start", + Q_ARG(QThread::Priority, QThread::IdlePriority))); + thread.exit(); + thread.wait(30s); +} + void tst_QThread::terminate() { #if defined(Q_OS_ANDROID) @@ -1229,9 +1287,10 @@ void tst_QThread::isRunningInFinished() } } -class DummyEventDispatcher : public QAbstractEventDispatcher { +class DummyEventDispatcher : public QAbstractEventDispatcherV2 +{ + Q_OBJECT public: - DummyEventDispatcher() : QAbstractEventDispatcher() {} bool processEvents(QEventLoop::ProcessEventsFlags) override { visited.storeRelaxed(true); emit awake(); @@ -1240,11 +1299,19 @@ public: } void registerSocketNotifier(QSocketNotifier *) override {} void unregisterSocketNotifier(QSocketNotifier *) override {} - void registerTimer(int, qint64, Qt::TimerType, QObject *) override {} - bool unregisterTimer(int) override { return false; } + void registerTimer(Qt::TimerId id, Duration, Qt::TimerType, QObject *) override + { + if (registeredTimerId <= Qt::TimerId::Invalid) + registeredTimerId = id; + } + bool unregisterTimer(Qt::TimerId id) override + { + Qt::TimerId oldId = std::exchange(registeredTimerId, Qt::TimerId::Invalid); + return id == oldId; + } bool unregisterTimers(QObject *) override { return false; } - QList<TimerInfo> registeredTimers(QObject *) const override { return QList<TimerInfo>(); } - int remainingTime(int) override { return 0; } + QList<TimerInfoV2> timersForObject(QObject *) const override { return {}; } + Duration remainingTime(Qt::TimerId) const override { return 0s; } void wakeUp() override {} void interrupt() override {} @@ -1254,25 +1321,47 @@ public: #endif QBasicAtomicInt visited; // bool + Qt::TimerId registeredTimerId = Qt::TimerId::Invalid; }; -class ThreadObj : public QObject +struct ThreadLocalContent { - Q_OBJECT -public slots: - void visit() { - emit visited(); + static inline const QMetaObject *atStart; + static inline const QMetaObject *atEnd; + QSemaphore *sem; + QBasicTimer timer; + + ThreadLocalContent(QObject *obj, QSemaphore *sem) + : sem(sem) + { + ensureEventDispatcher(); + atStart = QAbstractEventDispatcher::instance()->metaObject(); + timer.start(10s, obj); + } + ~ThreadLocalContent() + { + ensureEventDispatcher(); + atEnd = QAbstractEventDispatcher::instance()->metaObject(); + timer.stop(); + sem->release(); + } + + void ensureEventDispatcher() + { + // QEventLoop's constructor has a call to QThreadData::ensureEventDispatcher() + QEventLoop dummy; } -signals: - void visited(); }; void tst_QThread::customEventDispatcher() { + ThreadLocalContent::atStart = ThreadLocalContent::atEnd = nullptr; + QThread thr; // there should be no ED yet QVERIFY(!thr.eventDispatcher()); DummyEventDispatcher *ed = new DummyEventDispatcher; + QPointer<DummyEventDispatcher> weak_ed(ed); thr.setEventDispatcher(ed); // the new ED should be set QCOMPARE(thr.eventDispatcher(), ed); @@ -1281,25 +1370,39 @@ void tst_QThread::customEventDispatcher() thr.start(); // start() should not overwrite the ED QCOMPARE(thr.eventDispatcher(), ed); + QVERIFY(!weak_ed.isNull()); - ThreadObj obj; + QObject obj; obj.moveToThread(&thr); // move was successful? QCOMPARE(obj.thread(), &thr); - QEventLoop loop; - connect(&obj, SIGNAL(visited()), &loop, SLOT(quit()), Qt::QueuedConnection); - QMetaObject::invokeMethod(&obj, "visit", Qt::QueuedConnection); - loop.exec(); + + QSemaphore threadLocalSemaphore; + QMetaObject::invokeMethod(&obj, [&]() { +#ifndef Q_OS_WIN + // On Windows, the thread_locals are unsequenced between DLLs, so this + // could run after QThreadPrivate::finish() + static thread_local +#endif + ThreadLocalContent d(&obj, &threadLocalSemaphore); + }, Qt::BlockingQueuedConnection); + // test that the ED has really been used QVERIFY(ed->visited.loadRelaxed()); + // and it's ours + QCOMPARE(ThreadLocalContent::atStart->className(), "DummyEventDispatcher"); - QPointer<DummyEventDispatcher> weak_ed(ed); QVERIFY(!weak_ed.isNull()); thr.quit(); + // wait for thread to be stopped QVERIFY(thr.wait(30000)); + QVERIFY(threadLocalSemaphore.tryAcquire(1, 30s)); + // test that ED has been deleted QVERIFY(weak_ed.isNull()); + // test that ED was ours + QCOMPARE(ThreadLocalContent::atEnd->className(), "DummyEventDispatcher"); } class Job : public QObject @@ -1355,9 +1458,6 @@ void tst_QThread::quitLock() void tst_QThread::create() { -#if !QT_CONFIG(cxx11_future) - QSKIP("This test requires QThread::create"); -#else { const auto &function = [](){}; QScopedPointer<QThread> thread(QThread::create(function)); @@ -1597,7 +1697,6 @@ void tst_QThread::create() QVERIFY(!thread); } #endif // QT_NO_EXCEPTIONS -#endif // QT_CONFIG(cxx11_future) } void tst_QThread::createDestruction() diff --git a/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt index c41251df79..2c92ca002e 100644 --- a/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt +++ b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qthreadonce Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qthreadonce LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qthreadonce SOURCES qthreadonce.cpp diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp index a712903da8..b32f455241 100644 --- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp +++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qplatformdefs.h" diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h index 05c3788fd9..1f804433e4 100644 --- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h +++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QTHREADONCE_H diff --git a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp index c91d2bd110..37e1f744f3 100644 --- a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp +++ b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> diff --git a/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt index 4ee970335f..fee9c541db 100644 --- a/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt +++ b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qthreadpool Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qthreadpool LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qthreadpool SOURCES tst_qthreadpool.cpp diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 775dd85b86..2006016d47 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSemaphore> @@ -418,9 +418,6 @@ void tst_QThreadPool::expiryTimeout() void tst_QThreadPool::expiryTimeoutRace() // QTBUG-3786 { -#ifdef Q_OS_WIN - QSKIP("This test is unstable on Windows. See QTBUG-3786."); -#endif ExpiryTimeoutTask task; TestThreadPool threadPool; diff --git a/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt index 53fd8a1f81..14d8d7dd40 100644 --- a/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt +++ b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qthreadstorage Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qthreadstorage LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qthreadstorage SOURCES tst_qthreadstorage.cpp diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp index cc730cd4a1..3b3a4d4813 100644 --- a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp +++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QCoreApplication> #include <QtCore/QThreadStorage> diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp index b3debebdc1..ca382cf60c 100644 --- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #if QT_CONFIG(process) diff --git a/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt index da5a70bfd5..0a2830622e 100644 --- a/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt +++ b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qwaitcondition Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qwaitcondition LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qwaitcondition SOURCES tst_qwaitcondition.cpp diff --git a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp index 5c6566de38..4e3413afe8 100644 --- a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp +++ b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QReadWriteLock> diff --git a/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt index c8fd8d323d..5345522ea5 100644 --- a/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt +++ b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt @@ -5,6 +5,12 @@ ## tst_qwritelocker Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qwritelocker LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qwritelocker SOURCES tst_qwritelocker.cpp diff --git a/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp b/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp index fd8221d609..b4e6b45dbd 100644 --- a/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp +++ b/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> |