async_tick/
waiter.rs

1use async_ach_waker::pool::{WakerPool, WakerToken};
2use async_ach_waker::WakerEntity;
3use atomic_polyfill::{AtomicU64, Ordering::SeqCst};
4use core::ops::Deref;
5use core::task::Waker;
6use core::u64::MAX;
7
8pub struct Waiter<const N: usize> {
9    pool: WakerPool<u64, N>,
10    next: AtomicU64,
11}
12impl<const N: usize> Waiter<N> {
13    pub const fn new() -> Self {
14        Self {
15            pool: WakerPool::new(),
16            next: AtomicU64::new(MAX),
17        }
18    }
19    pub fn register(&self) -> Result<Token<N>, ()> {
20        let token = self.pool.register()?;
21        Ok(Token {
22            next: &self.next,
23            token,
24        })
25    }
26    pub fn take_next(&self) -> Option<u64> {
27        let next = self.next.swap(MAX, SeqCst);
28        if next == MAX {
29            None
30        } else {
31            Some(next)
32        }
33    }
34    pub fn set_next(&self, next: u64) {
35        self.next.fetch_min(next, SeqCst);
36    }
37}
38impl<const N: usize> Deref for Waiter<N> {
39    type Target = WakerPool<u64, N>;
40    fn deref(&self) -> &Self::Target {
41        &self.pool
42    }
43}
44
45pub struct Token<'a, const N: usize> {
46    next: &'a AtomicU64,
47    token: WakerToken<'a, u64, N>,
48}
49impl<'a, const N: usize> Token<'a, N> {
50    pub fn swap(&self, waker: Waker, deadline: u64) {
51        self.next.fetch_min(deadline, SeqCst);
52        self.token.swap(WakerEntity::new(waker, deadline));
53    }
54}