1use core::{fmt, pin::Pin, task::Poll, time::Duration};
5use s2n_quic_core::{
6 ensure, time,
7 time::{timer, timer::Provider},
8};
9use tracing::trace;
10
11#[macro_use]
12mod macros;
13
14#[cfg(any(test, feature = "testing"))]
15pub mod bach;
16#[cfg(feature = "tokio")]
17pub mod tokio;
18pub use time::clock::Cached;
19
20pub use time::Timestamp;
21
22use crate::either::Either;
23pub type SleepHandle = Pin<Box<dyn Sleep>>;
24
25pub trait Clock: 'static + Send + Sync + fmt::Debug + time::Clock {
26 fn sleep(&self, amount: Duration) -> (SleepHandle, Timestamp);
27
28 fn timer(&self) -> Timer
29 where
30 Self: Sized,
31 {
32 Timer::new(self)
33 }
34}
35
36impl<A, B> Clock for Either<A, B>
37where
38 A: Clock,
39 B: Clock,
40{
41 fn sleep(&self, amount: Duration) -> (SleepHandle, Timestamp) {
42 match self {
43 Either::A(a) => a.sleep(amount),
44 Either::B(b) => b.sleep(amount),
45 }
46 }
47}
48
49impl<A, B> time::Clock for Either<A, B>
50where
51 A: time::Clock,
52 B: time::Clock,
53{
54 fn get_time(&self) -> Timestamp {
55 match self {
56 Either::A(a) => a.get_time(),
57 Either::B(b) => b.get_time(),
58 }
59 }
60}
61
62pub trait Sleep: Clock + core::future::Future<Output = ()> {
63 fn update(self: Pin<&mut Self>, target: Timestamp);
64}
65
66pub struct Timer {
67 target: timer::Timer,
69 sleep: Pin<Box<dyn Sleep>>,
71}
72
73impl fmt::Debug for Timer {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 f.debug_struct("Timer")
76 .field("target", &self.target)
77 .finish()
78 }
79}
80
81impl Timer {
82 #[inline]
83 pub fn new(clock: &dyn Clock) -> Self {
84 const INITIAL_TIMEOUT: Duration = Duration::from_secs(1);
87
88 Self::new_with_timeout(clock, INITIAL_TIMEOUT)
89 }
90
91 #[inline]
92 pub fn new_with_timeout(clock: &dyn Clock, timeout: Duration) -> Self {
93 let (sleep, target) = clock.sleep(timeout);
94 let mut timer = timer::Timer::default();
95 timer.set(target);
96 Self {
97 target: timer,
98 sleep,
99 }
100 }
101
102 #[inline]
103 pub fn cancel(&mut self) {
104 trace!(cancel = ?self.target);
105 self.target.cancel();
106 }
107
108 pub async fn sleep(&mut self, target: Timestamp) {
109 use time::clock::Timer;
110 self.update(target);
111 core::future::poll_fn(|cx| self.poll_ready(cx)).await
112 }
113}
114
115impl time::clock::Timer for Timer {
116 #[inline]
117 fn poll_ready(&mut self, cx: &mut core::task::Context) -> Poll<()> {
118 ensure!(self.target.is_armed(), Poll::Ready(()));
119
120 let res = self.sleep.as_mut().poll(cx);
121
122 if res.is_ready() {
123 self.target.cancel();
125 }
126
127 res
128 }
129
130 #[inline]
131 fn update(&mut self, target: Timestamp) {
132 ensure!(self.target.next_expiration() != Some(target));
134
135 self.sleep.as_mut().update(target);
136 self.target.set(target);
137 }
138}
139
140impl timer::Provider for Timer {
141 fn timers<Q: timer::Query>(&self, query: &mut Q) -> timer::Result {
142 self.target.timers(query)
143 }
144}