compio_runtime/time/
future.rs1use std::{
2 cell::RefCell,
3 pin::Pin,
4 rc::Rc,
5 task::{Context, Poll},
6 time::{Duration, Instant},
7};
8
9use crate::{
10 Runtime,
11 time::{TimerRuntime, runtime::TimerKey, sleep_until},
12};
13
14#[derive(Debug)]
15pub(crate) struct TimerFuture {
16 key: TimerKey,
17 rt: Rc<RefCell<TimerRuntime>>,
18}
19
20impl TimerFuture {
21 pub fn try_new(instant: Instant) -> Option<Self> {
28 Runtime::with_current(|rt| {
29 let key = rt.timer_runtime.borrow_mut().insert(instant)?;
30 Some(Self {
31 key,
32 rt: rt.timer_runtime.clone(),
33 })
34 })
35 }
36}
37
38impl Future for TimerFuture {
39 type Output = ();
40
41 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
42 self.rt.borrow_mut().poll_timer(cx, &self.key)
43 }
44}
45
46impl Drop for TimerFuture {
47 fn drop(&mut self) {
48 self.rt.borrow_mut().cancel(&self.key)
49 }
50}
51
52compio_driver::assert_not_impl!(TimerFuture, Send);
53compio_driver::assert_not_impl!(TimerFuture, Sync);
54
55#[derive(Debug)]
65pub struct Interval {
66 first_ticked: bool,
67 start: Instant,
68 period: Duration,
69}
70
71impl Interval {
72 pub(crate) fn new(start: Instant, period: Duration) -> Self {
73 Self {
74 first_ticked: false,
75 start,
76 period,
77 }
78 }
79
80 pub async fn tick(&mut self) -> Instant {
85 if !self.first_ticked {
86 sleep_until(self.start).await;
87 self.first_ticked = true;
88 self.start
89 } else {
90 let now = Instant::now();
91 let next = now + self.period
92 - Duration::from_nanos(
93 ((now - self.start).as_nanos() % self.period.as_nanos()) as _,
94 );
95 sleep_until(next).await;
96 next
97 }
98 }
99}