diff options
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r-- | src/testlib/qtestcase.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 4023ae86eb..cebb934973 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1211,17 +1211,30 @@ void TestMethods::invokeTestOnData(int index) const class WatchDog : public QThread { - enum Expectation { + enum Expectation : std::size_t { + // bits 0..1: state ThreadStart, TestFunctionStart, TestFunctionEnd, ThreadEnd, + + // bits 2..: generation }; + static constexpr auto ExpectationMask = Expectation{ThreadStart | TestFunctionStart | TestFunctionEnd | ThreadEnd}; + static_assert(size_t(ExpectationMask) == 0x3); + static constexpr size_t GenerationShift = 2; + + static constexpr Expectation state(Expectation e) noexcept + { return Expectation{e & ExpectationMask}; } + static constexpr size_t generation(Expectation e) noexcept + { return e >> GenerationShift; } + static constexpr Expectation combine(Expectation e, size_t gen) noexcept + { return Expectation{e | (gen << GenerationShift)}; } bool waitFor(std::unique_lock<QtPrivate::mutex> &m, Expectation e) { auto expectationChanged = [this, e] { return expecting.load(std::memory_order_relaxed) != e; }; - switch (e) { + switch (state(e)) { case TestFunctionEnd: return waitCondition.wait_for(m, defaultTimeout(), expectationChanged); case ThreadStart: @@ -1235,7 +1248,13 @@ class WatchDog : public QThread void setExpectation(Expectation e) { + Q_ASSERT(generation(e) == 0); // no embedded generation allowed const auto locker = qt_scoped_lock(mutex); + auto cur = expecting.load(std::memory_order_relaxed); + auto gen = generation(cur); + if (e == TestFunctionStart) + ++gen; + e = combine(e, gen); expecting.store(e, std::memory_order_relaxed); waitCondition.notify_all(); } @@ -1273,7 +1292,7 @@ public: waitCondition.notify_all(); while (true) { Expectation e = expecting.load(std::memory_order_acquire); - switch (e) { + switch (state(e)) { case ThreadEnd: return; case ThreadStart: |