summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-22 22:28:32 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-22 22:28:33 +0200
commitc0f7cc3a3cc3f06b09591f25277f8083b3a55581 (patch)
treeecf3d3f49d6dc85b55fbdbe999e386ceda31ef39 /src/testlib
parent139240ac671953f0763308f235d8b868c1efe1b1 (diff)
parentaa6d7dd7ee306c0adbcd42b013d1e749072205bb (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/qtestcase.cpp84
1 files changed, 57 insertions, 27 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 990fc5679d..e29897abee 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -58,8 +58,7 @@
#include <QtCore/qdiriterator.h>
#include <QtCore/qtemporarydir.h>
#include <QtCore/qthread.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtCore/qmutex.h>
+#include <QtCore/private/qlocking_p.h>
#include <QtCore/qtestsupport_core.h>
@@ -85,6 +84,9 @@
#include <cmath>
#include <numeric>
#include <algorithm>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
#include <stdarg.h>
#include <stdio.h>
@@ -406,7 +408,7 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
#if QT_CONFIG(thread)
-static int defaultTimeout()
+static std::chrono::milliseconds defaultTimeout()
{
if (timeout == -1) {
bool ok = false;
@@ -415,7 +417,7 @@ static int defaultTimeout()
if (!ok || timeout <= 0)
timeout = 5*60*1000;
}
- return timeout;
+ return std::chrono::milliseconds{timeout};
}
#endif
@@ -1008,53 +1010,81 @@ void TestMethods::invokeTestOnData(int index) const
class WatchDog : public QThread
{
+ enum Expectation {
+ ThreadStart,
+ TestFunctionStart,
+ TestFunctionEnd,
+ ThreadEnd,
+ };
+
+ bool waitFor(std::unique_lock<std::mutex> &m, Expectation e) {
+ auto expectation = [this, e] { return expecting != e; };
+ switch (e) {
+ case TestFunctionEnd:
+ return waitCondition.wait_for(m, defaultTimeout(), expectation);
+ case ThreadStart:
+ case ThreadEnd:
+ case TestFunctionStart:
+ waitCondition.wait(m, expectation);
+ return true;
+ }
+ Q_UNREACHABLE();
+ return false;
+ }
+
public:
WatchDog()
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
+ std::unique_lock<std::mutex> locker(mutex);
+ expecting = ThreadStart;
start();
- waitCondition.wait(&mutex);
+ waitFor(locker, ThreadStart);
}
~WatchDog() {
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(0);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = ThreadEnd;
+ waitCondition.notify_all();
}
wait();
}
void beginTest() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(defaultTimeout());
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionEnd;
+ waitCondition.notify_all();
}
void testFinished() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
}
void run() override {
- QMutexLocker locker(&mutex);
- waitCondition.wakeAll();
+ std::unique_lock<std::mutex> locker(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
while (true) {
- int t = timeout.loadRelaxed();
- if (!t)
- break;
- if (Q_UNLIKELY(!waitCondition.wait(&mutex, t))) {
- stackTrace();
- qFatal("Test function timed out");
+ switch (expecting) {
+ case ThreadEnd:
+ return;
+ case ThreadStart:
+ Q_UNREACHABLE();
+ case TestFunctionStart:
+ case TestFunctionEnd:
+ if (Q_UNLIKELY(!waitFor(locker, expecting))) {
+ stackTrace();
+ qFatal("Test function timed out");
+ }
}
}
}
private:
- QBasicAtomicInt timeout;
- QMutex mutex;
- QWaitCondition waitCondition;
+ std::mutex mutex;
+ std::condition_variable waitCondition;
+ Expectation expecting;
};
#else // !QT_CONFIG(thread)