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}