diff options
Diffstat (limited to 'tests/auto/corelib/thread')
6 files changed, 952 insertions, 280 deletions
diff --git a/tests/auto/corelib/thread/qmutex/qmutex.pro b/tests/auto/corelib/thread/qmutex/qmutex.pro index 229e57eb89..cb9d364b71 100644 --- a/tests/auto/corelib/thread/qmutex/qmutex.pro +++ b/tests/auto/corelib/thread/qmutex/qmutex.pro @@ -2,3 +2,4 @@ CONFIG += testcase TARGET = tst_qmutex QT = core testlib SOURCES = tst_qmutex.cpp +win32:QT += core-private diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp index 594bae674c..bf778e9fd1 100644 --- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp @@ -31,16 +31,38 @@ #include <qatomic.h> #include <qcoreapplication.h> -#include <qdatetime.h> +#include <qelapsedtimer.h> #include <qmutex.h> #include <qthread.h> #include <qwaitcondition.h> +#ifdef Q_OS_WIN +#include <private/qsystemlibrary_p.h> +#include <cmath> +#endif + class tst_QMutex : public QObject { Q_OBJECT +public: + enum class TimeUnit { + Nanoseconds, + Microseconds, + Milliseconds, + Seconds, + }; + Q_ENUM(TimeUnit); + private slots: - void tryLock(); + void initTestCase(); + void convertToMilliseconds_data(); + void convertToMilliseconds(); + void tryLock_non_recursive(); + void try_lock_for_non_recursive(); + void try_lock_until_non_recursive(); + void tryLock_recursive(); + void try_lock_for_recursive(); + void try_lock_until_recursive(); void lock_unlock_locked_tryLock(); void stressTest(); void tryLockRace(); @@ -48,6 +70,8 @@ private slots: void tryLockNegative_data(); void tryLockNegative(); void moreStress(); +private: + void initializeSystemTimersResolution(); }; static const int iterations = 100; @@ -58,257 +82,922 @@ QSemaphore testsTurn; QSemaphore threadsTurn; enum { waitTime = 100 }; +uint systemTimersResolution = 1; + +#if QT_HAS_INCLUDE(<chrono>) +static Q_CONSTEXPR std::chrono::milliseconds waitTimeAsDuration(waitTime); +#endif + +/* + Depending on the OS, tryWaits may return early than expected because of the + resolution of the underlying timer is too coarse. E.g.: on Windows + WaitForSingleObjectEx does *not* use high resolution multimedia timers, and + it's actually very coarse, about 16msec by default. + + Try to find out the timer resolution in here, so that the tryLock tests can + actually take into account early wakes. +*/ +void tst_QMutex::initializeSystemTimersResolution() +{ +#ifdef Q_OS_WIN + // according to MSDN, Windows can default up to this + systemTimersResolution = 16; + + // private API. There's no way on Windows to otherwise know the + // actual resolution of the application's timers (you can only set it) + // cf. https://stackoverflow.com/questions/7685762/windows-7-timing-functions-how-to-use-getsystemtimeadjustment-correctly/11743614#11743614 + typedef NTSTATUS (NTAPI *NtQueryTimerResolutionType)(OUT PULONG MinimumResolution, + OUT PULONG MaximumResolution, + OUT PULONG ActualResolution); + + const NtQueryTimerResolutionType NtQueryTimerResolutionPtr = + reinterpret_cast<NtQueryTimerResolutionType>(QSystemLibrary::resolve(QStringLiteral("ntdll"), "NtQueryTimerResolution")); + + if (!NtQueryTimerResolutionPtr) + return; + + ULONG minimumResolution; + ULONG maximumResolution; + ULONG actualResolution; + + if (!NtQueryTimerResolutionPtr(&minimumResolution, &maximumResolution, &actualResolution)) { + // the result is in 100ns units => adjust to msec + const double actualResolutionMsec = actualResolution / 10000.0; + systemTimersResolution = static_cast<int>(std::ceil(actualResolutionMsec)); + } +#endif // Q_OS_WIN +} + +void tst_QMutex::initTestCase() +{ + initializeSystemTimersResolution(); +} -void tst_QMutex::tryLock() +void tst_QMutex::convertToMilliseconds_data() { - // test non-recursive mutex + QTest::addColumn<TimeUnit>("unit"); + QTest::addColumn<double>("doubleValue"); + QTest::addColumn<qint64>("intValue"); + QTest::addColumn<qint64>("expected"); + + + auto add = [](TimeUnit unit, double d, long long i, qint64 expected) { + const QScopedArrayPointer<char> enumName(QTest::toString(unit)); + QTest::newRow(qPrintable(QString::asprintf("%s:%f:%lld", enumName.data(), d, i))) + << unit << d << qint64(i) << expected; + }; + + auto forAllUnitsAdd = [=](double d, long long i, qint64 expected) { + for (auto unit : {TimeUnit::Nanoseconds, TimeUnit::Microseconds, TimeUnit::Milliseconds, TimeUnit::Seconds}) + add(unit, d, i, expected); + }; + + forAllUnitsAdd(-0.5, -1, 0); // all negative values result in 0 + + forAllUnitsAdd(0, 0, 0); + + add(TimeUnit::Nanoseconds, 1, 1, 1); + add(TimeUnit::Nanoseconds, 1000 * 1000, 1000 * 1000, 1); + add(TimeUnit::Nanoseconds, 1000 * 1000 + 0.5, 1000 * 1000 + 1, 2); + + add(TimeUnit::Microseconds, 1, 1, 1); + add(TimeUnit::Microseconds, 1000, 1000, 1); + add(TimeUnit::Microseconds, 1000 + 0.5, 1000 + 1, 2); + + add(TimeUnit::Milliseconds, 1, 1, 1); + add(TimeUnit::Milliseconds, 1.5, 2, 2); + + add(TimeUnit::Seconds, 0.9991, 1, 1000); + + // + // overflowing int results in INT_MAX (equivalent to a spurious wakeup after ~24 days); check it: + // + + // spot on: + add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000, INT_MAX * Q_INT64_C(1000) * 1000, INT_MAX); + add(TimeUnit::Microseconds, INT_MAX * 1000., INT_MAX * Q_INT64_C(1000), INT_MAX); + add(TimeUnit::Milliseconds, INT_MAX, INT_MAX, INT_MAX); + + // minimally above: + add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000 + 1, INT_MAX * Q_INT64_C(1000) * 1000 + 1, INT_MAX); + add(TimeUnit::Microseconds, INT_MAX * 1000. + 1, INT_MAX * Q_INT64_C(1000) + 1, INT_MAX); + add(TimeUnit::Milliseconds, INT_MAX + 1., INT_MAX + Q_INT64_C(1), INT_MAX); + add(TimeUnit::Seconds, INT_MAX / 1000. + 1, INT_MAX / 1000 + 1, INT_MAX); + + // minimally below: + add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000 - 1, INT_MAX * Q_INT64_C(1000) * 1000 - 1, INT_MAX); + add(TimeUnit::Microseconds, INT_MAX * 1000. - 1, INT_MAX * Q_INT64_C(1000) - 1, INT_MAX); + add(TimeUnit::Milliseconds, INT_MAX - 0.1, INT_MAX , INT_MAX); + +} + +void tst_QMutex::convertToMilliseconds() +{ +#if !QT_HAS_INCLUDE(<chrono>) + QSKIP("This test requires <chrono>"); +#else + QFETCH(TimeUnit, unit); + QFETCH(double, doubleValue); + QFETCH(qint64, intValue); + QFETCH(qint64, expected); + + Q_CONSTEXPR qint64 maxShort = std::numeric_limits<short>::max(); + Q_CONSTEXPR qint64 maxInt = std::numeric_limits<int>::max(); + Q_CONSTEXPR qint64 maxUInt = std::numeric_limits<uint>::max(); + + switch (unit) { +#define CASE(Unit, Period) \ + case TimeUnit::Unit: \ + DO(double, Period, doubleValue); \ + if (intValue < maxShort) \ + DO(short, Period, short(intValue)); \ + if (intValue < maxInt) \ + DO(int, Period, int(intValue)); \ + DO(qint64, Period, intValue); \ + if (intValue >= 0) { \ + if (intValue < maxUInt) \ + DO(uint, Period, uint(intValue)); \ + DO(quint64, Period, quint64(intValue)); \ + } \ + break +#define DO(Rep, Period, val) \ + do { \ + const std::chrono::duration<Rep, Period> wait((val)); \ + QCOMPARE(QMutex::convertToMilliseconds(wait), expected); \ + } while (0) + + CASE(Nanoseconds, std::nano); + CASE(Microseconds, std::micro); + CASE(Milliseconds, std::milli); + CASE(Seconds, std::ratio<1>); +#undef DO +#undef CASE + } +#endif +} + +void tst_QMutex::tryLock_non_recursive() +{ + class Thread : public QThread { - class Thread : public QThread + public: + void run() { - public: - void run() - { - testsTurn.release(); - - // TEST 1: thread can't acquire lock - threadsTurn.acquire(); - QVERIFY(!normalMutex.tryLock()); - testsTurn.release(); - - // TEST 2: thread can acquire lock - threadsTurn.acquire(); - QVERIFY(normalMutex.tryLock()); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - QVERIFY(!normalMutex.tryLock()); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - normalMutex.unlock(); - testsTurn.release(); - - // TEST 3: thread can't acquire lock, timeout = waitTime - threadsTurn.acquire(); - QTime timer; - timer.start(); - QVERIFY(!normalMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() >= waitTime); - testsTurn.release(); - - // TEST 4: thread can acquire lock, timeout = waitTime - threadsTurn.acquire(); - timer.start(); - QVERIFY(normalMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() <= waitTime); - 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); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - normalMutex.unlock(); - testsTurn.release(); - - // TEST 5: thread can't acquire lock, timeout = 0 - threadsTurn.acquire(); - QVERIFY(!normalMutex.tryLock(0)); - testsTurn.release(); - - // TEST 6: thread can acquire lock, timeout = 0 - threadsTurn.acquire(); - timer.start(); - QVERIFY(normalMutex.tryLock(0)); - QVERIFY(timer.elapsed() < waitTime); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - QVERIFY(!normalMutex.tryLock(0)); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - normalMutex.unlock(); - testsTurn.release(); - - // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) - threadsTurn.acquire(); - timer.start(); - QVERIFY(normalMutex.tryLock(3000)); - QVERIFY(timer.elapsed() < 3000); - normalMutex.unlock(); - testsTurn.release(); - - threadsTurn.acquire(); - } - }; + testsTurn.release(); + + // TEST 1: thread can't acquire lock + threadsTurn.acquire(); + QVERIFY(!normalMutex.tryLock()); + testsTurn.release(); + + // TEST 2: thread can acquire lock + threadsTurn.acquire(); + QVERIFY(normalMutex.tryLock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.tryLock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 3: thread can't acquire lock, timeout = waitTime + threadsTurn.acquire(); + QElapsedTimer timer; + timer.start(); + QVERIFY(!normalMutex.tryLock(waitTime)); + QVERIFY(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); + 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); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 5: thread can't acquire lock, timeout = 0 + threadsTurn.acquire(); + QVERIFY(!normalMutex.tryLock(0)); + testsTurn.release(); + + // TEST 6: thread can acquire lock, timeout = 0 + threadsTurn.acquire(); + timer.start(); + QVERIFY(normalMutex.tryLock(0)); + QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.tryLock(0)); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) + threadsTurn.acquire(); + timer.start(); + QVERIFY(normalMutex.tryLock(3000)); + QVERIFY(timer.elapsed() < 3000 + systemTimersResolution); + normalMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; - Thread thread; - thread.start(); + Thread thread; + thread.start(); + + // TEST 1: thread can't acquire lock + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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) + testsTurn.acquire(); + normalMutex.lock(); + threadsTurn.release(); + QThread::msleep(100); + normalMutex.unlock(); + + // wait for thread to finish + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +} - // TEST 1: thread can't acquire lock - testsTurn.acquire(); - normalMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - threadsTurn.release(); - - // 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 - testsTurn.acquire(); - normalMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - threadsTurn.release(); - - // 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 - testsTurn.acquire(); - normalMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - threadsTurn.release(); - - // 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) - testsTurn.acquire(); - normalMutex.lock(); - threadsTurn.release(); - QThread::msleep(100); - normalMutex.unlock(); - - // wait for thread to finish - testsTurn.acquire(); - threadsTurn.release(); - thread.wait(); - } +void tst_QMutex::try_lock_for_non_recursive() { +#if !QT_HAS_INCLUDE(<chrono>) + QSKIP("This test requires <chrono>"); +#else + class Thread : public QThread + { + public: + void run() + { + testsTurn.release(); + + // TEST 1: thread can't acquire lock + threadsTurn.acquire(); + QVERIFY(!normalMutex.try_lock()); + testsTurn.release(); + + // TEST 2: thread can acquire lock + threadsTurn.acquire(); + QVERIFY(normalMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 3: thread can't acquire lock, timeout = waitTime + threadsTurn.acquire(); + QElapsedTimer timer; + timer.start(); + QVERIFY(!normalMutex.try_lock_for(waitTimeAsDuration)); + QVERIFY(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); + 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); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 5: thread can't acquire lock, timeout = 0 + threadsTurn.acquire(); + QVERIFY(!normalMutex.try_lock_for(std::chrono::milliseconds::zero())); + testsTurn.release(); + + // TEST 6: thread can acquire lock, timeout = 0 + threadsTurn.acquire(); + timer.start(); + QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds::zero())); + QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.try_lock_for(std::chrono::milliseconds::zero())); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) + threadsTurn.acquire(); + timer.start(); + QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds(3000))); + QVERIFY(timer.elapsed() < 3000 + systemTimersResolution); + normalMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; + + Thread thread; + thread.start(); + + // TEST 1: thread can't acquire lock + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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) + testsTurn.acquire(); + normalMutex.lock(); + threadsTurn.release(); + QThread::msleep(100); + normalMutex.unlock(); + + // wait for thread to finish + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +#endif +} - // test recursive mutex +void tst_QMutex::try_lock_until_non_recursive() +{ +#if !QT_HAS_INCLUDE(<chrono>) + QSKIP("This test requires <chrono>"); +#else + class Thread : public QThread { - class Thread : public QThread + public: + void run() { - public: - void run() - { - testsTurn.release(); - - threadsTurn.acquire(); - QVERIFY(!recursiveMutex.tryLock()); - testsTurn.release(); - - threadsTurn.acquire(); - QVERIFY(recursiveMutex.tryLock()); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - QVERIFY(recursiveMutex.tryLock()); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - testsTurn.release(); - - threadsTurn.acquire(); - QTime timer; - timer.start(); - QVERIFY(!recursiveMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() >= waitTime); - QVERIFY(!recursiveMutex.tryLock(0)); - testsTurn.release(); - - threadsTurn.acquire(); - timer.start(); - QVERIFY(recursiveMutex.tryLock(waitTime)); - QVERIFY(timer.elapsed() <= waitTime); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - QVERIFY(recursiveMutex.tryLock(waitTime)); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - testsTurn.release(); - - threadsTurn.acquire(); - QVERIFY(!recursiveMutex.tryLock(0)); - QVERIFY(!recursiveMutex.tryLock(0)); - testsTurn.release(); - - threadsTurn.acquire(); - timer.start(); - QVERIFY(recursiveMutex.tryLock(0)); - QVERIFY(timer.elapsed() < waitTime); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - QVERIFY(recursiveMutex.tryLock(0)); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - testsTurn.release(); - - threadsTurn.acquire(); - } - }; + const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution); + testsTurn.release(); + + // TEST 1: thread can't acquire lock + threadsTurn.acquire(); + QVERIFY(!normalMutex.try_lock()); + testsTurn.release(); + + // TEST 2: thread can acquire lock + threadsTurn.acquire(); + QVERIFY(normalMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 3: thread can't acquire lock, timeout = waitTime + threadsTurn.acquire(); + auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; + QVERIFY(!normalMutex.try_lock_until(endTimePoint)); + QVERIFY(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); + 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); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 5: thread can't acquire lock, timeout = 0 + threadsTurn.acquire(); + QVERIFY(!normalMutex.try_lock_until(std::chrono::steady_clock::now())); + testsTurn.release(); + + // TEST 6: thread can acquire lock, timeout = 0 + 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); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.try_lock_until(std::chrono::steady_clock::now())); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) + 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); + normalMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; - Thread thread; - thread.start(); + Thread thread; + thread.start(); + + // TEST 1: thread can't acquire lock + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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 + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // 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) + testsTurn.acquire(); + normalMutex.lock(); + threadsTurn.release(); + QThread::msleep(100); + normalMutex.unlock(); + + // wait for thread to finish + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +#endif +} - // thread can't acquire lock - testsTurn.acquire(); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - threadsTurn.release(); - - // thread can acquire lock - testsTurn.acquire(); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - threadsTurn.release(); - - // thread can't acquire lock, timeout = waitTime - testsTurn.acquire(); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - threadsTurn.release(); - - // thread can acquire lock, timeout = waitTime - testsTurn.acquire(); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - threadsTurn.release(); - - // thread can't acquire lock, timeout = 0 - testsTurn.acquire(); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(0, 1)); - recursiveMutex.lock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 2)); - threadsTurn.release(); - - // thread can acquire lock, timeout = 0 - testsTurn.acquire(); - QVERIFY(lockCount.testAndSetRelaxed(2, 1)); - recursiveMutex.unlock(); - QVERIFY(lockCount.testAndSetRelaxed(1, 0)); - recursiveMutex.unlock(); - threadsTurn.release(); - - // stop thread - testsTurn.acquire(); - threadsTurn.release(); - thread.wait(); - } +void tst_QMutex::tryLock_recursive() +{ + class Thread : public QThread + { + public: + void run() + { + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.tryLock()); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(recursiveMutex.tryLock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.tryLock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + QElapsedTimer timer; + timer.start(); + QVERIFY(!recursiveMutex.tryLock(waitTime)); + QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution); + QVERIFY(!recursiveMutex.tryLock(0)); + testsTurn.release(); + + threadsTurn.acquire(); + timer.start(); + QVERIFY(recursiveMutex.tryLock(waitTime)); + QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.tryLock(waitTime)); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.tryLock(0)); + QVERIFY(!recursiveMutex.tryLock(0)); + testsTurn.release(); + + threadsTurn.acquire(); + timer.start(); + QVERIFY(recursiveMutex.tryLock(0)); + QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.tryLock(0)); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; + + Thread thread; + thread.start(); + + // thread can't acquire lock + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = waitTime + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = waitTime + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = 0 + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = 0 + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // stop thread + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +} + +void tst_QMutex::try_lock_for_recursive() +{ +#if !QT_HAS_INCLUDE(<chrono>) + QSKIP("This test requires <chrono>"); +#else + class Thread : public QThread + { + public: + void run() + { + const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.try_lock()); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(recursiveMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + QElapsedTimer timer; + timer.start(); + QVERIFY(!recursiveMutex.try_lock_for(waitTimeAsDuration)); + QVERIFY(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); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.try_lock_for(waitTimeAsDuration)); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); + QVERIFY(!recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); + testsTurn.release(); + + threadsTurn.acquire(); + timer.start(); + QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); + QVERIFY(timer.elapsed() < waitTime + systemTimersResolution); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero())); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; + + Thread thread; + thread.start(); + + // thread can't acquire lock + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = waitTime + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = waitTime + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = 0 + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = 0 + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // stop thread + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +#endif +} + +void tst_QMutex::try_lock_until_recursive() +{ +#if !QT_HAS_INCLUDE(<chrono>) + QSKIP("This test requires <chrono>"); +#else + class Thread : public QThread + { + public: + void run() + { + const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.try_lock()); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(recursiveMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.try_lock()); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; + QVERIFY(!recursiveMutex.try_lock_until(endTimePoint)); + QVERIFY(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); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration; + QVERIFY(recursiveMutex.try_lock_until(endTimePoint)); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + QVERIFY(!recursiveMutex.try_lock_until(std::chrono::steady_clock::now())); + QVERIFY(!recursiveMutex.try_lock_until(std::chrono::steady_clock::now())); + testsTurn.release(); + + 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); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.try_lock_until(std::chrono::steady_clock::now())); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); + } + }; + + Thread thread; + thread.start(); + + // thread can't acquire lock + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = waitTime + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = waitTime + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = 0 + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock, timeout = 0 + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // stop thread + testsTurn.acquire(); + threadsTurn.release(); + thread.wait(); +#endif } class mutex_Thread : public QThread @@ -439,7 +1128,7 @@ enum { one_minute = 6 * 1000, //not really one minute, but else it is too long. class StressTestThread : public QThread { - QTime t; + QElapsedTimer t; public: static QBasicAtomicInt lockCount; static QBasicAtomicInt sentinel; @@ -491,7 +1180,7 @@ public: void run() { - QTime t; + QElapsedTimer t; t.start(); do { if (mutex.tryLock()) @@ -619,7 +1308,7 @@ void tst_QMutex::tryLockNegative() class MoreStressTestThread : public QThread { - QTime t; + QElapsedTimer t; public: static QAtomicInt lockCount; static QAtomicInt sentinel[threadCount]; diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index 341bd21e5a..8597bf1a6d 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -350,15 +350,9 @@ const int AlphabetSize = sizeof(alphabet) - 1; const int BufferSize = 4096; // GCD of BufferSize and alphabet size must be 1 char buffer[BufferSize]; -#ifndef Q_OS_WINCE const int ProducerChunkSize = 3; const int ConsumerChunkSize = 7; const int Multiplier = 10; -#else -const int ProducerChunkSize = 2; -const int ConsumerChunkSize = 5; -const int Multiplier = 3; -#endif // note: the code depends on the fact that DataSize is a multiple of // ProducerChunkSize, ConsumerChunkSize, and BufferSize diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index bbd319d2db..0efbc5d01e 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -95,9 +95,7 @@ private slots: void requestTermination(); -#ifndef Q_OS_WINCE void stressTest(); -#endif void quitLock(); }; @@ -664,7 +662,7 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data) #if defined Q_OS_UNIX const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this); Q_UNUSED(state); -#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT) +#elif defined(Q_OS_WINRT) nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL); #elif defined Q_OS_WIN unsigned thrdid = 0; @@ -684,11 +682,7 @@ void NativeThreadWrapper::join() #if defined Q_OS_UNIX pthread_join(nativeThreadHandle, 0); #elif defined Q_OS_WIN -#ifndef Q_OS_WINCE WaitForSingleObjectEx(nativeThreadHandle, INFINITE, FALSE); -#else - WaitForSingleObject(nativeThreadHandle, INFINITE); -#endif CloseHandle(nativeThreadHandle); #endif } @@ -874,13 +868,8 @@ void tst_QThread::adoptedThreadExecFinished() void tst_QThread::adoptMultipleThreads() { #if defined(Q_OS_WIN) - // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. -# if defined(Q_OS_WINCE) - const int numThreads = 20; -# else // need to test lots of threads, so that we exceed MAXIMUM_WAIT_OBJECTS in qt_adopted_thread_watcher() const int numThreads = 200; -# endif #else const int numThreads = 5; #endif @@ -911,13 +900,8 @@ void tst_QThread::adoptMultipleThreads() void tst_QThread::adoptMultipleThreadsOverlap() { #if defined(Q_OS_WIN) - // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. -# if defined(Q_OS_WINCE) - const int numThreads = 20; -# else // need to test lots of threads, so that we exceed MAXIMUM_WAIT_OBJECTS in qt_adopted_thread_watcher() const int numThreads = 200; -# endif #else const int numThreads = 5; #endif @@ -950,7 +934,6 @@ void tst_QThread::adoptMultipleThreadsOverlap() QCOMPARE(recorder.activationCount.load(), numThreads); } -#ifndef Q_OS_WINCE // Disconnects on WinCE void tst_QThread::stressTest() { @@ -962,7 +945,6 @@ void tst_QThread::stressTest() t.wait(one_minute); } } -#endif class Syncronizer : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp index ba64bf2963..a9af182ed8 100644 --- a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp +++ b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp @@ -120,7 +120,7 @@ void tst_QThreadOnce::sameThread() void tst_QThreadOnce::multipleThreads() { -#if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS) +#if defined(Q_OS_VXWORKS) const int NumberOfThreads = 20; #else const int NumberOfThreads = 100; diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp index f3eba5c823..49a3b3e4db 100644 --- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp @@ -40,10 +40,8 @@ #include <pthread.h> #endif #ifdef Q_OS_WIN -#ifndef Q_OS_WINCE -#include <process.h> -#endif -#include <windows.h> +# include <process.h> +# include <qt_windows.h> #endif class tst_QThreadStorage : public QObject @@ -202,6 +200,13 @@ void testAdoptedThreadStorageWin(void *p) } QObject::connect(QThread::currentThread(), SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); } +#ifdef Q_OS_WINRT +unsigned __stdcall testAdoptedThreadStorageWinRT(void *p) +{ + testAdoptedThreadStorageWin(p); + return 0; +} +#endif void *testAdoptedThreadStorageUnix(void *pointers) { testAdoptedThreadStorageWin(pointers); @@ -219,13 +224,14 @@ void tst_QThreadStorage::adoptedThreads() const int state = pthread_create(&thread, 0, testAdoptedThreadStorageUnix, &pointers); QCOMPARE(state, 0); pthread_join(thread, 0); -#elif defined Q_OS_WIN && !defined(Q_OS_WINRT) +#elif defined Q_OS_WINRT + HANDLE thread; + thread = (HANDLE) _beginthreadex(NULL, 0, testAdoptedThreadStorageWinRT, &pointers, 0, 0); + QVERIFY(thread); + WaitForSingleObjectEx(thread, INFINITE, FALSE); +#elif defined Q_OS_WIN HANDLE thread; -#if defined(Q_OS_WINCE) - thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)testAdoptedThreadStorageWin, &pointers, 0, NULL); -#else thread = (HANDLE)_beginthread(testAdoptedThreadStorageWin, 0, &pointers); -#endif QVERIFY(thread); WaitForSingleObject(thread, INFINITE); #endif |