common/thread: Fix data race in is_set
As report by tsan, Event::Set can write is_set while WaitFor and friends are reading from it. To address this issue, make is_set an atomic.
This commit is contained in:
parent
4efaecf125
commit
f119ef798b
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -25,13 +26,13 @@ public:
|
||||||
|
|
||||||
void Wait() {
|
void Wait() {
|
||||||
std::unique_lock lk{mutex};
|
std::unique_lock lk{mutex};
|
||||||
condvar.wait(lk, [&] { return is_set; });
|
condvar.wait(lk, [&] { return is_set.load(); });
|
||||||
is_set = false;
|
is_set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaitFor(const std::chrono::nanoseconds& time) {
|
bool WaitFor(const std::chrono::nanoseconds& time) {
|
||||||
std::unique_lock lk{mutex};
|
std::unique_lock lk{mutex};
|
||||||
if (!condvar.wait_for(lk, time, [this] { return is_set; }))
|
if (!condvar.wait_for(lk, time, [this] { return is_set.load(); }))
|
||||||
return false;
|
return false;
|
||||||
is_set = false;
|
is_set = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -40,7 +41,7 @@ public:
|
||||||
template <class Clock, class Duration>
|
template <class Clock, class Duration>
|
||||||
bool WaitUntil(const std::chrono::time_point<Clock, Duration>& time) {
|
bool WaitUntil(const std::chrono::time_point<Clock, Duration>& time) {
|
||||||
std::unique_lock lk{mutex};
|
std::unique_lock lk{mutex};
|
||||||
if (!condvar.wait_until(lk, time, [this] { return is_set; }))
|
if (!condvar.wait_until(lk, time, [this] { return is_set.load(); }))
|
||||||
return false;
|
return false;
|
||||||
is_set = false;
|
is_set = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,9 +55,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_set = false;
|
|
||||||
std::condition_variable condvar;
|
std::condition_variable condvar;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
|
std::atomic_bool is_set{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Barrier {
|
class Barrier {
|
||||||
|
|
Loading…
Reference in a new issue