21#include "pw_async2/dispatcher.h"
22#include "pw_async2/future.h"
23#include "pw_chrono/virtual_clock.h"
24#include "pw_containers/intrusive_list.h"
25#include "pw_sync/interrupt_spin_lock.h"
26#include "pw_sync/lock_annotations.h"
27#include "pw_toolchain/no_destructor.h"
40void AssertTimeFutureObjectsAllGone(
bool empty);
46template <
typename Clock>
62template <
typename Clock>
66 internal::AssertTimeFutureObjectsAllGone(futures_.empty());
69 typename Clock::time_point
now()
override = 0;
80 return WaitUntil(
now() + delay +
typename Clock::duration(1));
88 typename Clock::time_point timestamp) {
121template <typename Clock>
125 using value_type =
typename Clock::time_point;
127 constexpr TimeFuture() : provider_(
nullptr) {}
133 *
this = std::move(other);
137 std::lock_guard lock(internal::time_lock());
140 provider_ = other.provider_;
141 expiration_ = other.expiration_;
144 if (!other.unlisted()) {
145 auto previous = provider_->futures_.before_begin();
146 while (&*std::next(previous) != &other) {
152 other.unlist(&*previous);
153 provider_->futures_.insert_after(previous, *
this);
165 return expiration_ != value_type{} && provider_ !=
nullptr;
169 return expiration_ != value_type{} && provider_ ==
nullptr;
172 Poll<typename Clock::time_point> Pend(Context& cx)
174 PW_ASSERT(is_pendable());
176 std::lock_guard lock(internal::time_lock());
177 if (this->unlisted()) {
179 return Ready(expiration_);
206 friend class TimeProvider<Clock>;
211 TimeFuture(TimeProvider<Clock>& provider,
212 typename Clock::time_point expiration)
213 : waker_(), provider_(&provider), expiration_(expiration) {
214 PW_ASSERT(expiration != value_type{});
216 std::lock_guard lock(internal::time_lock());
224 if (provider_->now() >= expiration_) {
228 if (provider_->futures_.empty() ||
229 provider_->futures_.front().expiration_ > expiration_) {
230 provider_->futures_.push_front(*
this);
231 provider_->DoInvokeAt(expiration_);
234 auto current = provider_->futures_.begin();
235 while (std::next(current) != provider_->futures_.end() &&
236 std::next(current)->expiration_ < expiration_) {
239 provider_->futures_.insert_after(current, *
this);
243 std::lock_guard lock(internal::time_lock());
253 if (this->unlisted()) {
256 if (&provider_->futures_.front() ==
this) {
257 provider_->futures_.pop_front();
258 if (provider_->futures_.empty()) {
259 provider_->DoCancel();
261 provider_->DoInvokeAt(provider_->futures_.front().expiration_);
266 provider_->futures_.remove(*
this);
277 TimeProvider<Clock>* provider_
PW_GUARDED_BY(internal::time_lock());
278 typename Clock::time_point expiration_
PW_GUARDED_BY(internal::time_lock());
281template <
typename Clock>
283 std::lock_guard lock(internal::time_lock());
284 while (!futures_.empty()) {
285 if (futures_.front().expiration_ >
now) {
289 futures_.front().waker_.Wake();
290 futures_.pop_front();
Definition: intrusive_forward_list.h:99
Definition: time_provider.h:123
~TimeFuture()
Definition: time_provider.h:162
Definition: time_provider.h:63
virtual void DoCancel()=0
Optimistically cancels all pending DoInvokeAt requests.
Clock::time_point now() override=0
Returns the current time.
TimeFuture< Clock > WaitFor(typename Clock::duration delay)
Definition: time_provider.h:75
virtual void DoInvokeAt(typename Clock::time_point)=0
TimeFuture< Clock > WaitUntil(typename Clock::time_point timestamp)
Definition: time_provider.h:87
Definition: virtual_clock.h:31
Definition: intrusive_list.h:88
Definition: interrupt_spin_lock.h:50
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:337
void RunExpired(typename Clock::time_point now)
Definition: time_provider.h:282
#define PW_ASYNC_STORE_WAKER(context, waker_or_queue_out, wait_reason_string)
Definition: waker.h:58
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_NO_LOCK_SAFETY_ANALYSIS
Definition: lock_annotations.h:292
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:176