Skip to main content

async_ach_waker/
list.rs

1//! Only work on single thread
2
3use crate::WakerEntity;
4use ach_linked::LinkedList;
5pub use ach_linked::Node;
6
7pub struct WakerList<T> {
8    list: LinkedList<WakerEntity<T>>,
9}
10impl<T> WakerList<T> {
11    pub const fn new() -> Self {
12        Self {
13            list: LinkedList::new(),
14        }
15    }
16    /// Register a waker
17    ///
18    /// Safety:
19    /// This function is only safe as long as `node` is guaranteed to
20    /// get removed from the list before it gets moved or dropped.
21    pub unsafe fn register(&self, waker: &mut Node<WakerEntity<T>>) {
22        self.list.push(waker)
23    }
24    /// Removes a node from the LinkedList.
25    pub fn remove(&self, waker: &mut Node<WakerEntity<T>>) {
26        self.list.remove(waker)
27    }
28    /// Wake a waiter, and remove it.
29    ///
30    /// Returns false if the list is empty.
31    pub fn wake_one(&self) -> bool {
32        if let Some(list) = self.list.take_all() {
33            let mut waker = unsafe { &mut *(list as *mut Node<WakerEntity<T>>) };
34            let ret = loop {
35                if waker.wake() {
36                    break true;
37                } else {
38                    if let Some(list) = waker.next() {
39                        waker = list
40                    } else {
41                        break false;
42                    }
43                }
44            };
45            unsafe { self.list.push_list(list) };
46            ret
47        } else {
48            false
49        }
50    }
51    /// Wake all waiter, and remove it.
52    ///
53    /// returns the number of had waked
54    pub fn wake_all(&self) -> usize {
55        let mut num = 0;
56        if let Some(list) = self.list.take_all() {
57            let mut waker = unsafe { &mut *(list as *mut Node<WakerEntity<T>>) };
58            loop {
59                if waker.wake() {
60                    num += 1;
61                }
62                if let Some(list) = waker.next() {
63                    waker = list
64                } else {
65                    break;
66                }
67            }
68            unsafe { self.list.push_list(list) };
69        }
70        num
71    }
72    /// Retains only the elements specified by the predicate.
73    ///
74    /// In other words, remove all elements e such that f(&e) returns false.
75    /// This method operates in place, visiting each element exactly once in the original order,
76    /// but not preserves the order of the retained elements.
77    pub fn retain(&self, mut f: impl FnMut(&WakerEntity<T>) -> bool) {
78        let list = self.list.take_all();
79        if let Some(list) = list {
80            let mut remain: Option<&mut Node<WakerEntity<T>>> = None;
81            for waker in list.into_iter() {
82                if f(&*waker) {
83                    if let Some(remain) = &mut remain {
84                        unsafe { remain.push(waker) };
85                    } else {
86                        remain = Some(waker);
87                    }
88                }
89            }
90            if let Some(remain) = remain {
91                unsafe { self.list.push_list(remain) };
92            }
93        }
94    }
95}