use super::std_timer_scheduler::StdTimerScheduler;
use super::std_timer_waiter::StdTimerWaiter;
use crate::{
TimeError,
TimerUnavailableError,
};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{
Context,
Poll,
};
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);
}
}
}