AsyncSignal now keeps track if the future has been polled.

This commit is contained in:
Filipe Rodrigues 2024-12-22 18:33:58 +00:00
parent 8b936d8f1d
commit 33d480aa3e
Signed by: zenithsiz
SSH Key Fingerprint: SHA256:Mb5ppb3Sh7IarBO/sBTXLHbYEOz37hJAlslLQPPAPaU
2 changed files with 23 additions and 2 deletions

View File

@ -45,6 +45,12 @@ impl<F: Future<Output = Result<T, E>>, T, E> LoadableSignal<F> {
self.inner.is_suspended()
}
/// Gets whether this future has been polled
#[must_use]
pub fn has_polled(&self) -> bool {
self.inner.has_polled()
}
/// Loads this value asynchronously and returns the value
pub async fn load(&self) -> Result<BorrowRef<'_, T, E>, E>
where

View File

@ -74,6 +74,9 @@ struct Inner<F: Future> {
/// Whether we're suspended
is_suspended: AtomicBool,
/// Whether we've been polled.
has_polled: AtomicBool,
/// Value
value: OnceLock<F::Output>,
}
@ -112,6 +115,7 @@ impl<F: Future> AsyncSignal<F> {
trigger: Trigger::new(),
}),
is_suspended: AtomicBool::new(is_suspended),
has_polled: AtomicBool::new(false),
value: OnceLock::new(),
});
Self { inner }
@ -128,6 +132,12 @@ impl<F: Future> AsyncSignal<F> {
self.inner.is_suspended.load(atomic::Ordering::Acquire)
}
/// Gets whether this future has been polled
#[must_use]
pub fn has_polled(&self) -> bool {
self.inner.has_polled.load(atomic::Ordering::Acquire)
}
/// Loads this value asynchronously and returns the value
pub async fn load(&self) -> &'_ F::Output {
// Gather subcribers before polling
@ -160,7 +170,7 @@ impl<F: Future> AsyncSignal<F> {
let mut fut = unsafe { Pin::new_unchecked(&mut *fut) };
// Then poll it
match fut.as_mut().poll(cx) {
let output = match fut.as_mut().poll(cx) {
Poll::Ready(value) => {
// Drop the future once we load it
let _: Option<F> = inner_fut.take();
@ -168,7 +178,12 @@ impl<F: Future> AsyncSignal<F> {
Ok(value)
},
Poll::Pending => Err(()),
}
};
// And set that we've polled
self.inner.has_polled.store(true, atomic::Ordering::Release);
output
})
.ok()?;