use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::task::Context;
use std::task::Poll;
use super::std_timer_scheduler::StdTimerScheduler;
use super::std_timer_waiter::StdTimerWaiter;
use crate::TimeError;
use crate::TimerUnavailableError;
pub(crate) struct StdTimerFuture {
scheduler: Arc<StdTimerScheduler>,
waiter_id: Option<u64>,
waiter: Arc<StdTimerWaiter>,
}
impl StdTimerFuture {
#[must_use]
#[inline]
pub(crate) const fn new(scheduler: Arc<StdTimerScheduler>, waiter_id: u64, waiter: Arc<StdTimerWaiter>) -> Self {
Self {
scheduler,
waiter_id: Some(waiter_id),
waiter,
}
}
}
impl Future for StdTimerFuture {
type Output = Result<(), TimeError>;
fn poll(self: Pin<&mut Self>, context: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
match this.waiter.poll(context) {
Poll::Pending => Poll::Pending,
Poll::Ready(Ok(())) => {
this.waiter_id = None;
Poll::Ready(Ok(()))
}
Poll::Ready(Err(())) => {
this.waiter_id = None;
Poll::Ready(Err(TimeError::TimerUnavailable {
source: TimerUnavailableError::SchedulerWorkerTerminated,
}))
}
}
}
}
impl Drop for StdTimerFuture {
#[inline]
fn drop(&mut self) {
if let Some(waiter_id) = self.waiter_id.take() {
self.scheduler.cancel(waiter_id);
}
}
}