AtomicCondition: add wait*_value helpers

This commit is contained in:
Tom 2020-07-17 23:37:33 +02:00
parent fed1e55a23
commit f62a81797a
2 changed files with 95 additions and 0 deletions

View File

@ -65,6 +65,18 @@ public:
return this->condvar_.wait(lock, std::forward<Args>(args)...);
}
template<typename... Args>
auto wait_value(ValueType value, Args&&... args) const
{
std::unique_lock lock(this->mutex_);
return this->condvar_.wait(
lock,
std::forward<Args>(args)...,
[this, &value](){
return this->value_.load() == value;
});
}
template<typename... Args>
auto wait_for(Args&&... args) const
{
@ -72,6 +84,18 @@ public:
return this->condvar_.wait_for(lock, std::forward<Args>(args)...);
}
template<typename... Args>
auto wait_for_value(ValueType value, Args&&... args) const
{
std::unique_lock lock(this->mutex_);
return this->condvar_.wait_for(
lock,
std::forward<Args>(args)...,
[this, &value](){
return this->value_.load() == value;
});
}
template<typename... Args>
auto wait_until(Args&&... args) const
{
@ -79,6 +103,18 @@ public:
return this->condvar_.wait_until(lock, std::forward<Args>(args)...);
}
template<typename... Args>
auto wait_until_value(ValueType value, Args&&... args) const
{
std::unique_lock lock(this->mutex_);
return this->condvar_.wait_until(
lock,
std::forward<Args>(args)...,
[this, &value](){
return this->value_.load() == value;
});
}
private:
std::atomic<ValueType> value_;
mutable std::mutex mutex_;

View File

@ -85,6 +85,23 @@ TEST_CASE("wait-pred")
REQUIRE( future.get() == true );
}
TEST_CASE("wait-value")
{
sgnl::AtomicCondition condition(0);
std::future<int> future =
std::async(
std::launch::async,
[&condition](){ condition.wait_value(23); return condition.get(); });
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::yield();
condition.notify_all();
condition.set_and_notify_one(23);
REQUIRE( future.get() == 23 );
}
TEST_CASE("wait-for-predicate")
{
sgnl::AtomicCondition condition(23);
@ -105,6 +122,24 @@ TEST_CASE("wait-for-predicate")
REQUIRE( condition.get() == 42 );
}
TEST_CASE("wait-for-value")
{
sgnl::AtomicCondition condition(23);
std::future<void> future =
std::async(
std::launch::async,
[&condition](){
condition.wait_for_value(42, std::chrono::hours(1000)); });
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::yield();
condition.set_and_notify_all(42);
future.wait();
REQUIRE( condition.get() == 42 );
}
TEST_CASE("wait-for-predicate-simple")
{
sgnl::AtomicCondition condition(23);
@ -146,6 +181,30 @@ TEST_CASE("wait-until-predicate")
REQUIRE( condition.get() == 42 );
}
TEST_CASE("wait-until-value")
{
sgnl::AtomicCondition condition(23);
std::future<int> future =
std::async(
std::launch::async,
[&condition](){
condition.wait_until_value(
42,
std::chrono::system_clock::now() + std::chrono::hours(1));
return condition.get();
});
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::yield();
condition.notify_all();
condition.set(42);
condition.notify_all();
REQUIRE( future.get() == 42 );
REQUIRE( condition.get() == 42 );
}
TEST_CASE("sigwait")
{
sgnl::SignalHandler signal_handler({SIGUSR1});