xref: /DragonOS/kernel/src/libs/notifier.rs (revision 4fda81ce81939d83b74c8042d6fb4223deff3685)
1 #![allow(dead_code)]
2 use core::fmt::Debug;
3 
4 use crate::{
5     kwarn,
6     libs::{rwlock::RwLock, spinlock::SpinLock},
7     syscall::SystemError,
8 };
9 use alloc::{sync::Arc, vec::Vec};
10 
11 /// @brief 通知链节点
12 pub trait NotifierBlock<V: Clone + Copy, T>: Debug + Send + Sync {
13     /// @brief 通知链中注册的回调函数类型
14     fn notifier_call(&self, action: V, data: Option<&T>) -> i32;
15     /// @brief 通知链节点的优先级
16     fn priority(&self) -> i32;
17 }
18 
19 /// @brief 通知链
20 // TODO: 考虑使用红黑树封装
21 #[derive(Debug)]
22 struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>);
23 
24 impl<V: Clone + Copy, T> NotifierChain<V, T> {
25     pub fn new() -> Self {
26         Self(vec![])
27     }
28 
29     /// @brief 将节点注册到通知链
30     /// @param unique_priority 检查通知链中优先级的唯一性
31     pub fn register(
32         &mut self,
33         block: Arc<dyn NotifierBlock<V, T>>,
34         unique_priority: bool,
35     ) -> Result<(), SystemError> {
36         let mut index: usize = 0;
37 
38         // 在 notifier chain中寻找第一个优先级比要插入块低的块
39         for b in self.0.iter() {
40             // 判断之前是否已经注册过该节点
41             if Arc::as_ptr(&block) == Arc::as_ptr(b) {
42                 kwarn!(
43                     "notifier callback {:?} already registered",
44                     Arc::as_ptr(&block)
45                 );
46                 return Err(SystemError::EEXIST);
47             }
48 
49             if block.priority() > b.priority() {
50                 break;
51             }
52 
53             // 优先级唯一性检测
54             if block.priority() == b.priority() && unique_priority {
55                 return Err(SystemError::EBUSY);
56             }
57 
58             index += 1;
59         }
60 
61         // 插入 notifier chain
62         self.0.insert(index, block);
63         return Ok(());
64     }
65 
66     /// @brief 在通知链中取消注册节点
67     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
68         let remove = self
69             .0
70             .drain_filter(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
71         match remove.count() {
72             0 => return Err(SystemError::ENOENT),
73             _ => return Ok(()),
74         }
75     }
76 
77     /// 通知链进行事件通知
78     ///
79     /// ## 参数
80     ///
81     /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数
82     ///
83     /// ## 返回
84     ///
85     /// (最后一次回调函数的返回值,回调次数)
86     ///
87     /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能
88     pub fn call_chain(
89         &self,
90         action: V,
91         data: Option<&T>,
92         nr_to_call: Option<usize>,
93     ) -> (i32, usize) {
94         let mut ret: i32 = 0;
95         let mut nr_calls: usize = 0;
96 
97         for b in self.0.iter() {
98             if nr_to_call.is_some_and(|x| nr_calls >= x) {
99                 break;
100             }
101             ret = b.notifier_call(action, data);
102             nr_calls += 1;
103         }
104         return (ret, nr_calls);
105     }
106 }
107 
108 /// @brief 原子的通知链,使用 SpinLock 进行同步
109 #[derive(Debug)]
110 pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>);
111 
112 impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> {
113     pub fn new() -> Self {
114         Self(SpinLock::new(NotifierChain::<V, T>::new()))
115     }
116 
117     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
118         let mut notifier_chain_guard = self.0.lock();
119         return notifier_chain_guard.register(block, false);
120     }
121 
122     pub fn register_unique_prio(
123         &mut self,
124         block: Arc<dyn NotifierBlock<V, T>>,
125     ) -> Result<(), SystemError> {
126         let mut notifier_chain_guard = self.0.lock();
127         return notifier_chain_guard.register(block, true);
128     }
129 
130     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
131         let mut notifier_chain_guard = self.0.lock();
132         return notifier_chain_guard.unregister(block);
133     }
134 
135     pub fn call_chain(
136         &self,
137         action: V,
138         data: Option<&T>,
139         nr_to_call: Option<usize>,
140     ) -> (i32, usize) {
141         let notifier_chain_guard = self.0.lock();
142         return notifier_chain_guard.call_chain(action, data, nr_to_call);
143     }
144 }
145 
146 /// @brief 可阻塞的通知链,使用 RwLock 进行同步
147 // TODO: 使用 semaphore 封装
148 #[derive(Debug)]
149 pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
150 
151 impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
152     pub fn new() -> Self {
153         Self(RwLock::new(NotifierChain::<V, T>::new()))
154     }
155 
156     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
157         let mut notifier_chain_guard = self.0.write();
158         return notifier_chain_guard.register(block, false);
159     }
160 
161     pub fn register_unique_prio(
162         &mut self,
163         block: Arc<dyn NotifierBlock<V, T>>,
164     ) -> Result<(), SystemError> {
165         let mut notifier_chain_guard = self.0.write();
166         return notifier_chain_guard.register(block, true);
167     }
168 
169     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
170         let mut notifier_chain_guard = self.0.write();
171         return notifier_chain_guard.unregister(block);
172     }
173 
174     pub fn call_chain(
175         &self,
176         action: V,
177         data: Option<&T>,
178         nr_to_call: Option<usize>,
179     ) -> (i32, usize) {
180         let notifier_chain_guard = self.0.read();
181         return notifier_chain_guard.call_chain(action, data, nr_to_call);
182     }
183 }
184 
185 /// @brief 原始的通知链,由调用者自行考虑同步
186 pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
187 
188 impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
189     pub fn new() -> Self {
190         Self(NotifierChain::<V, T>::new())
191     }
192 
193     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
194         return self.0.register(block, false);
195     }
196 
197     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
198         return self.0.unregister(block);
199     }
200 
201     pub fn call_chain(
202         &self,
203         action: V,
204         data: Option<&T>,
205         nr_to_call: Option<usize>,
206     ) -> (i32, usize) {
207         return self.0.call_chain(action, data, nr_to_call);
208     }
209 }
210