1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Only work on single thread

use crate::WakerEntity;
use ach_linked::LinkedList;
pub use ach_linked::Node;

pub struct WakerList<T> {
    list: LinkedList<WakerEntity<T>>,
}
impl<T> WakerList<T> {
    pub const fn new() -> Self {
        Self {
            list: LinkedList::new(),
        }
    }
    /// Register a waker
    ///
    /// Safety:
    /// This function is only safe as long as `node` is guaranteed to
    /// get removed from the list before it gets moved or dropped.
    pub unsafe fn register(&self, waker: &mut Node<WakerEntity<T>>) {
        self.list.push(waker)
    }
    /// Removes a node from the LinkedList.
    pub fn remove(&self, waker: &mut Node<WakerEntity<T>>) {
        self.list.remove(waker)
    }
    /// Wake a waiter, and remove it.
    ///
    /// Returns false if the list is empty.
    pub fn wake_one(&self) -> bool {
        if let Some(list) = self.list.take_all() {
            let mut waker = unsafe { &mut *(list as *mut Node<WakerEntity<T>>) };
            let ret = loop {
                if waker.wake() {
                    break true;
                } else {
                    if let Some(list) = waker.next() {
                        waker = list
                    } else {
                        break false;
                    }
                }
            };
            unsafe { self.list.push_list(list) };
            ret
        } else {
            false
        }
    }
    /// Wake all waiter, and remove it.
    ///
    /// returns the number of had waked
    pub fn wake_all(&self) -> usize {
        let mut num = 0;
        if let Some(list) = self.list.take_all() {
            let mut waker = unsafe { &mut *(list as *mut Node<WakerEntity<T>>) };
            loop {
                if waker.wake() {
                    num += 1;
                }
                if let Some(list) = waker.next() {
                    waker = list
                } else {
                    break;
                }
            }
            unsafe { self.list.push_list(list) };
        }
        num
    }
    /// Retains only the elements specified by the predicate.
    ///
    /// In other words, remove all elements e such that f(&e) returns false.
    /// This method operates in place, visiting each element exactly once in the original order,
    /// but not preserves the order of the retained elements.
    pub fn retain(&self, mut f: impl FnMut(&WakerEntity<T>) -> bool) {
        let list = self.list.take_all();
        if let Some(list) = list {
            let mut remain: Option<&mut Node<WakerEntity<T>>> = None;
            for waker in list.into_iter() {
                if f(&*waker) {
                    if let Some(remain) = &mut remain {
                        unsafe { remain.push(waker) };
                    } else {
                        remain = Some(waker);
                    }
                }
            }
            if let Some(remain) = remain {
                unsafe { self.list.push_list(remain) };
            }
        }
    }
}