File stoplight.hpp
File List > illixr > stoplight.hpp
Go to the documentation of this file
#pragma once
#include "phonebook.hpp"
#include
#include
#include
namespace ILLIXR {
class event {
public:
void set(bool new_value = true) {
{
std::lock_guard lock{mutex_};
value_ = new_value;
}
if (new_value) {
cv_.notify_all();
}
}
void clear() {
set(false);
}
bool is_set() const {
return value_;
}
void wait() const {
std::unique_lock<std::mutex> lock{mutex_};
// Check if we even need to wait
if (value_) {
return;
}
cv_.wait(lock, [this] {
return value_.load();
});
}
template<class Clock, class Rep, class Period>
[[maybe_unused]] bool wait_timeout(const std::chrono::duration<Rep, Period>& duration) const {
auto timeout_time = Clock::now() + duration;
if (value_) {
return true;
}
std::unique_lock<std::mutex> lock{mutex_};
while (cv_.wait_until(lock, timeout_time) != std::cv_status::timeout) {
if (value_) {
return true;
}
}
return false;
}
private:
mutable std::mutex mutex_;
mutable std::condition_variable cv_;
std::atomic<bool> value_ = false;
};
class stoplight : public phonebook::service {
public:
void wait_for_ready() const {
ready_.wait();
}
void signal_ready() {
ready_.set();
}
bool check_should_stop() const {
return should_stop_.is_set();
}
void wait_for_should_stop() const {
should_stop_.wait();
}
void signal_should_stop() {
should_stop_.set();
}
void wait_for_shutdown_complete() const {
shutdown_complete_.wait();
}
bool check_shutdown_complete() const {
return shutdown_complete_.is_set();
}
void signal_shutdown_complete() {
shutdown_complete_.set();
}
private:
event ready_;
event should_stop_;
event shutdown_complete_;
};
} // namespace ILLIXR