diff --git a/bricks/sync/waitable_atomic.h b/bricks/sync/waitable_atomic.h index 83329815..ad6efa4e 100644 --- a/bricks/sync/waitable_atomic.h +++ b/bricks/sync/waitable_atomic.h @@ -199,11 +199,11 @@ class WaitableAtomic { f(); } - bool Wait(std::function predicate) const { + bool Wait(std::function pred = [](const data_t& e) { return static_cast(e); }) const { std::unique_lock lock(data_mutex_); - if (!predicate(data_)) { + if (!pred(data_)) { const data_t& data = data_; - data_condition_variable_.wait(lock, [&predicate, &data] { return predicate(data); }); + data_condition_variable_.wait(lock, [&pred, &data] { return pred(data); }); } return true; } @@ -237,6 +237,16 @@ class WaitableAtomic { return true; } + template + bool WaitFor(T duration) const { + std::unique_lock lock(data_mutex_); + if (!static_cast(data_)) { + const data_t& data = data_; + return data_condition_variable_.wait_for(lock, duration, [&data] { return static_cast(data); }); + } + return true; + } + #ifndef CURRENT_FOR_CPP14 // NOTE(dkorolev): Deliberately not bothering with C++14 for these three- and four-argument `WaitFor()`-s. @@ -337,8 +347,10 @@ class WaitableAtomic { struct WaitableAtomicSubscriberRemoverImpl final : WaitableAtomicSubscriberRemover { WaitableAtomic& self_; const size_t id_; - WaitableAtomicSubscriberRemoverImpl(WaitableAtomic& self, size_t id) : self_(self), id_(id) {} - void Remove() override { + // TODO(dkorolev): Use `DISALLOW_COPY_AND_ASSIGN`?! + WaitableAtomicSubscriberRemoverImpl(WaitableAtomicSubscriberRemoverImpl const&) = delete; + WaitableAtomicSubscriberRemoverImpl& operator=(WaitableAtomicSubscriberRemoverImpl const&) = delete; + WaitableAtomicSubscriberRemoverImpl(WaitableAtomic& self, size_t id) : self_(self), id_(id) {} void Remove() override { // Okay to only lock the subscribers map, but not the data. std::lock_guard lock(self_.subscribers_mutex_); self_.subscribers_.erase(id_);