wasmer_wasix/fs/
notification.rs1use std::{
2 collections::VecDeque,
3 sync::Mutex,
4 task::{Poll, Waker},
5};
6
7use virtual_mio::{InterestHandler, InterestType};
8
9#[derive(Debug)]
10struct NotificationState {
11 counter: u64,
14 is_semaphore: bool,
16 wakers: VecDeque<Waker>,
18 interest_handler: Option<Box<dyn InterestHandler>>,
20}
21
22impl NotificationState {
23 fn add_waker(&mut self, waker: &Waker) {
24 if !self.wakers.iter().any(|a| a.will_wake(waker)) {
25 self.wakers.push_front(waker.clone());
26 }
27 }
28
29 fn wake_all(&mut self) {
30 while let Some(waker) = self.wakers.pop_front() {
31 waker.wake();
32 }
33 if let Some(handler) = self.interest_handler.as_mut() {
34 handler.push_interest(InterestType::Readable);
35 }
36 }
37
38 fn inc(&mut self, val: u64) {
39 self.counter += val;
40 self.wake_all();
41 }
42
43 fn dec(&mut self) -> u64 {
44 let val = self.counter;
45 if self.is_semaphore {
46 if self.counter > 0 {
47 self.counter -= 1;
48 if self.counter > 0 {
49 self.wake_all();
50 }
51 }
52 } else {
53 self.counter = 0;
54 }
55 val
56 }
57}
58
59#[derive(Debug)]
60pub struct NotificationInner {
61 state: Mutex<NotificationState>,
63}
64
65impl NotificationInner {
66 pub fn new(initial_val: u64, is_semaphore: bool) -> Self {
67 Self {
68 state: Mutex::new(NotificationState {
69 counter: initial_val,
70 is_semaphore,
71 wakers: Default::default(),
72 interest_handler: None,
73 }),
74 }
75 }
76 pub fn poll(&self, waker: &Waker) -> Poll<usize> {
77 let mut state = self.state.lock().unwrap();
78 state.add_waker(waker);
79
80 if state.counter > 0 {
81 Poll::Ready(state.counter as usize)
82 } else {
83 Poll::Pending
84 }
85 }
86
87 pub fn write(&self, val: u64) {
88 let mut state = self.state.lock().unwrap();
89 state.inc(val);
90 }
91
92 pub fn read(&self, waker: &Waker) -> Poll<u64> {
93 let mut state = self.state.lock().unwrap();
94 state.add_waker(waker);
95 match state.dec() {
96 0 => Poll::Pending,
97 res => Poll::Ready(res),
98 }
99 }
100
101 pub fn try_read(&self) -> Option<u64> {
102 let mut state = self.state.lock().unwrap();
103 match state.dec() {
104 0 => None,
105 res => Some(res),
106 }
107 }
108
109 pub fn reset(&self) {
110 let mut state = self.state.lock().unwrap();
111 state.counter = 0;
112 }
113
114 pub fn set_interest_handler(&self, handler: Box<dyn InterestHandler>) {
115 let mut state = self.state.lock().unwrap();
116 state.interest_handler.replace(handler);
117 }
118
119 pub fn remove_interest_handler(&self) -> Option<Box<dyn InterestHandler>> {
120 let mut state = self.state.lock().unwrap();
121 state.interest_handler.take()
122 }
123}