1use std::io::{Error, Result};
22use std::os::unix::io::{AsRawFd, RawFd};
23use std::pin::Pin;
24use std::task::{Context, Poll};
25use std::time::{Duration, Instant};
26
27use futures_core::ready;
28use timerfd::{SetTimeFlags, TimerFd as InnerTimerFd, TimerState};
29use tokio::io::unix::AsyncFd;
30use tokio::io::{AsyncRead, Interest, ReadBuf};
31
32pub use timerfd::ClockId;
33
34mod delay;
35mod interval;
39
40pub use delay::Delay;
41pub use interval::Interval;
42pub struct TimerFd(AsyncFd<InnerTimerFd>);
47
48impl TimerFd {
49 pub fn new(clock: ClockId) -> std::io::Result<Self> {
50 let fd = InnerTimerFd::new_custom(clock, true, true)?;
51 let inner = AsyncFd::with_interest(fd, Interest::READABLE)?;
52 Ok(TimerFd(inner))
53 }
54
55 fn set_state(&mut self, state: TimerState, flags: SetTimeFlags) {
56 (self.0).get_mut().set_state(state, flags);
57 }
58}
59
60fn read_u64(fd: RawFd) -> Result<u64> {
61 let mut buf = [0u8; 8];
62 let rv = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, 8) };
63 match rv {
64 len if len >= 0 => Ok(u64::from_ne_bytes(buf)),
65 _err => Err(Error::last_os_error()),
66 }
67}
68
69impl AsyncRead for TimerFd {
70 fn poll_read(
71 mut self: Pin<&mut Self>,
72 cx: &mut Context<'_>,
73 buf: &mut ReadBuf<'_>,
74 ) -> Poll<Result<()>> {
75 let inner = self.as_mut();
76 let fd = inner.0.as_raw_fd();
77
78 loop {
79 let mut guard = ready!(inner.0.poll_read_ready(cx))?;
80 match guard.try_io(|_| read_u64(fd)) {
81 Ok(res) => {
82 let num = res?;
83 buf.put_slice(&num.to_ne_bytes());
84 break;
85 }
86 Err(_) => continue,
87 }
88 }
89 Poll::Ready(Ok(()))
90 }
91}
92
93pub fn sleep(duration: Duration) -> Delay {
95 Delay::new(Instant::now() + duration).expect("can't create delay")
96}