Fix thread-sanitizer warning about a data race
Not 100% sure if this is a bug in tsan, but turning expected into an atomic variable will avoid the warnings. Change-Id: I6d6a5d58f90258d201ae3880473228638de0a215 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
224fccdaec
commit
a8a38f7caa
@ -1016,7 +1016,7 @@ class WatchDog : public QThread
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool waitFor(std::unique_lock<QtPrivate::mutex> &m, Expectation e) {
|
bool waitFor(std::unique_lock<QtPrivate::mutex> &m, Expectation e) {
|
||||||
auto expectationChanged = [this, e] { return expecting != e; };
|
auto expectationChanged = [this, e] { return expecting.load(std::memory_order_relaxed) != e; };
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case TestFunctionEnd:
|
case TestFunctionEnd:
|
||||||
return waitCondition.wait_for(m, defaultTimeout(), expectationChanged);
|
return waitCondition.wait_for(m, defaultTimeout(), expectationChanged);
|
||||||
@ -1035,14 +1035,14 @@ public:
|
|||||||
{
|
{
|
||||||
setObjectName(QLatin1String("QtTest Watchdog"));
|
setObjectName(QLatin1String("QtTest Watchdog"));
|
||||||
auto locker = qt_unique_lock(mutex);
|
auto locker = qt_unique_lock(mutex);
|
||||||
expecting = ThreadStart;
|
expecting.store(ThreadStart, std::memory_order_relaxed);
|
||||||
start();
|
start();
|
||||||
waitFor(locker, ThreadStart);
|
waitFor(locker, ThreadStart);
|
||||||
}
|
}
|
||||||
~WatchDog() {
|
~WatchDog() {
|
||||||
{
|
{
|
||||||
const auto locker = qt_scoped_lock(mutex);
|
const auto locker = qt_scoped_lock(mutex);
|
||||||
expecting = ThreadEnd;
|
expecting.store(ThreadEnd, std::memory_order_relaxed);
|
||||||
waitCondition.notify_all();
|
waitCondition.notify_all();
|
||||||
}
|
}
|
||||||
wait();
|
wait();
|
||||||
@ -1050,29 +1050,30 @@ public:
|
|||||||
|
|
||||||
void beginTest() {
|
void beginTest() {
|
||||||
const auto locker = qt_scoped_lock(mutex);
|
const auto locker = qt_scoped_lock(mutex);
|
||||||
expecting = TestFunctionEnd;
|
expecting.store(TestFunctionEnd, std::memory_order_relaxed);
|
||||||
waitCondition.notify_all();
|
waitCondition.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void testFinished() {
|
void testFinished() {
|
||||||
const auto locker = qt_scoped_lock(mutex);
|
const auto locker = qt_scoped_lock(mutex);
|
||||||
expecting = TestFunctionStart;
|
expecting.store(TestFunctionStart, std::memory_order_relaxed);
|
||||||
waitCondition.notify_all();
|
waitCondition.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
auto locker = qt_unique_lock(mutex);
|
auto locker = qt_unique_lock(mutex);
|
||||||
expecting = TestFunctionStart;
|
expecting.store(TestFunctionStart, std::memory_order_release);
|
||||||
waitCondition.notify_all();
|
waitCondition.notify_all();
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (expecting) {
|
Expectation e = expecting.load(std::memory_order_acquire);
|
||||||
|
switch (e) {
|
||||||
case ThreadEnd:
|
case ThreadEnd:
|
||||||
return;
|
return;
|
||||||
case ThreadStart:
|
case ThreadStart:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
case TestFunctionStart:
|
case TestFunctionStart:
|
||||||
case TestFunctionEnd:
|
case TestFunctionEnd:
|
||||||
if (Q_UNLIKELY(!waitFor(locker, expecting))) {
|
if (Q_UNLIKELY(!waitFor(locker, e))) {
|
||||||
stackTrace();
|
stackTrace();
|
||||||
qFatal("Test function timed out");
|
qFatal("Test function timed out");
|
||||||
}
|
}
|
||||||
@ -1083,7 +1084,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QtPrivate::mutex mutex;
|
QtPrivate::mutex mutex;
|
||||||
QtPrivate::condition_variable waitCondition;
|
QtPrivate::condition_variable waitCondition;
|
||||||
Expectation expecting;
|
std::atomic<Expectation> expecting;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // !QT_CONFIG(thread)
|
#else // !QT_CONFIG(thread)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user