xref: /DragonOS/kernel/src/libs/notifier.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
126887c63SLoGin #![allow(dead_code)]
206d5e247SLoGin use core::fmt::Debug;
306d5e247SLoGin 
4*2eab6dd7S曾俊 use crate::libs::{rwlock::RwLock, spinlock::SpinLock};
5729a96efSXshine use alloc::{sync::Arc, vec::Vec};
6*2eab6dd7S曾俊 use log::warn;
791e9d4abSLoGin use system_error::SystemError;
8729a96efSXshine 
9729a96efSXshine /// @brief 通知链节点
1006d5e247SLoGin pub trait NotifierBlock<V: Clone + Copy, T>: Debug + Send + Sync {
11729a96efSXshine     /// @brief 通知链中注册的回调函数类型
notifier_call(&self, action: V, data: Option<&T>) -> i321206d5e247SLoGin     fn notifier_call(&self, action: V, data: Option<&T>) -> i32;
13729a96efSXshine     /// @brief 通知链节点的优先级
priority(&self) -> i3214729a96efSXshine     fn priority(&self) -> i32;
15729a96efSXshine }
16729a96efSXshine 
17729a96efSXshine /// @brief 通知链
18729a96efSXshine // TODO: 考虑使用红黑树封装
1906d5e247SLoGin #[derive(Debug)]
2006d5e247SLoGin struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>);
21729a96efSXshine 
2206d5e247SLoGin impl<V: Clone + Copy, T> NotifierChain<V, T> {
new() -> Self23729a96efSXshine     pub fn new() -> Self {
24729a96efSXshine         Self(vec![])
25729a96efSXshine     }
26729a96efSXshine 
27729a96efSXshine     /// @brief 将节点注册到通知链
28729a96efSXshine     /// @param unique_priority 检查通知链中优先级的唯一性
register( &mut self, block: Arc<dyn NotifierBlock<V, T>>, unique_priority: bool, ) -> Result<(), SystemError>29729a96efSXshine     pub fn register(
30729a96efSXshine         &mut self,
3106d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
32729a96efSXshine         unique_priority: bool,
33729a96efSXshine     ) -> Result<(), SystemError> {
34729a96efSXshine         let mut index: usize = 0;
35729a96efSXshine 
36729a96efSXshine         // 在 notifier chain中寻找第一个优先级比要插入块低的块
37729a96efSXshine         for b in self.0.iter() {
38729a96efSXshine             // 判断之前是否已经注册过该节点
39b5b571e0SLoGin             if Arc::ptr_eq(&block, b) {
40*2eab6dd7S曾俊                 warn!(
41729a96efSXshine                     "notifier callback {:?} already registered",
42729a96efSXshine                     Arc::as_ptr(&block)
43729a96efSXshine                 );
44729a96efSXshine                 return Err(SystemError::EEXIST);
45729a96efSXshine             }
46729a96efSXshine 
47729a96efSXshine             if block.priority() > b.priority() {
48729a96efSXshine                 break;
49729a96efSXshine             }
50729a96efSXshine 
51729a96efSXshine             // 优先级唯一性检测
52729a96efSXshine             if block.priority() == b.priority() && unique_priority {
53729a96efSXshine                 return Err(SystemError::EBUSY);
54729a96efSXshine             }
55729a96efSXshine 
56729a96efSXshine             index += 1;
57729a96efSXshine         }
58729a96efSXshine 
59729a96efSXshine         // 插入 notifier chain
60729a96efSXshine         self.0.insert(index, block);
61729a96efSXshine         return Ok(());
62729a96efSXshine     }
63729a96efSXshine 
64729a96efSXshine     /// @brief 在通知链中取消注册节点
unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>6506d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
66b5b571e0SLoGin         let remove = self.0.extract_if(|b| Arc::ptr_eq(&block, b));
67729a96efSXshine         match remove.count() {
68729a96efSXshine             0 => return Err(SystemError::ENOENT),
69729a96efSXshine             _ => return Ok(()),
70729a96efSXshine         }
71729a96efSXshine     }
72729a96efSXshine 
7306d5e247SLoGin     /// 通知链进行事件通知
7406d5e247SLoGin     ///
7506d5e247SLoGin     /// ## 参数
7606d5e247SLoGin     ///
7706d5e247SLoGin     /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数
7806d5e247SLoGin     ///
7906d5e247SLoGin     /// ## 返回
8006d5e247SLoGin     ///
8106d5e247SLoGin     /// (最后一次回调函数的返回值,回调次数)
8206d5e247SLoGin     ///
8306d5e247SLoGin     /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能
call_chain( &self, action: V, data: Option<&T>, nr_to_call: Option<usize>, ) -> (i32, usize)84729a96efSXshine     pub fn call_chain(
85729a96efSXshine         &self,
8606d5e247SLoGin         action: V,
87729a96efSXshine         data: Option<&T>,
88729a96efSXshine         nr_to_call: Option<usize>,
89729a96efSXshine     ) -> (i32, usize) {
90729a96efSXshine         let mut ret: i32 = 0;
91729a96efSXshine         let mut nr_calls: usize = 0;
92729a96efSXshine 
93729a96efSXshine         for b in self.0.iter() {
94729a96efSXshine             if nr_to_call.is_some_and(|x| nr_calls >= x) {
95729a96efSXshine                 break;
96729a96efSXshine             }
97729a96efSXshine             ret = b.notifier_call(action, data);
98729a96efSXshine             nr_calls += 1;
99729a96efSXshine         }
100729a96efSXshine         return (ret, nr_calls);
101729a96efSXshine     }
102729a96efSXshine }
103729a96efSXshine 
104729a96efSXshine /// @brief 原子的通知链,使用 SpinLock 进行同步
10506d5e247SLoGin #[derive(Debug)]
10606d5e247SLoGin pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>);
107729a96efSXshine 
108b5b571e0SLoGin impl<V: Clone + Copy, T> Default for AtomicNotifierChain<V, T> {
default() -> Self109b5b571e0SLoGin     fn default() -> Self {
110b5b571e0SLoGin         Self::new()
111b5b571e0SLoGin     }
112b5b571e0SLoGin }
113b5b571e0SLoGin 
11406d5e247SLoGin impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> {
new() -> Self115729a96efSXshine     pub fn new() -> Self {
11606d5e247SLoGin         Self(SpinLock::new(NotifierChain::<V, T>::new()))
117729a96efSXshine     }
118729a96efSXshine 
register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>11906d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
120729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
121729a96efSXshine         return notifier_chain_guard.register(block, false);
122729a96efSXshine     }
123729a96efSXshine 
register_unique_prio( &mut self, block: Arc<dyn NotifierBlock<V, T>>, ) -> Result<(), SystemError>124729a96efSXshine     pub fn register_unique_prio(
125729a96efSXshine         &mut self,
12606d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
127729a96efSXshine     ) -> Result<(), SystemError> {
128729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
129729a96efSXshine         return notifier_chain_guard.register(block, true);
130729a96efSXshine     }
131729a96efSXshine 
unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>13206d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
133729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
134729a96efSXshine         return notifier_chain_guard.unregister(block);
135729a96efSXshine     }
136729a96efSXshine 
call_chain( &self, action: V, data: Option<&T>, nr_to_call: Option<usize>, ) -> (i32, usize)137729a96efSXshine     pub fn call_chain(
138729a96efSXshine         &self,
13906d5e247SLoGin         action: V,
140729a96efSXshine         data: Option<&T>,
141729a96efSXshine         nr_to_call: Option<usize>,
142729a96efSXshine     ) -> (i32, usize) {
143729a96efSXshine         let notifier_chain_guard = self.0.lock();
144729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
145729a96efSXshine     }
146729a96efSXshine }
147729a96efSXshine 
148729a96efSXshine /// @brief 可阻塞的通知链,使用 RwLock 进行同步
149729a96efSXshine // TODO: 使用 semaphore 封装
15006d5e247SLoGin #[derive(Debug)]
15106d5e247SLoGin pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
152729a96efSXshine 
15306d5e247SLoGin impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
new() -> Self154729a96efSXshine     pub fn new() -> Self {
15506d5e247SLoGin         Self(RwLock::new(NotifierChain::<V, T>::new()))
156729a96efSXshine     }
157729a96efSXshine 
register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>15806d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
159729a96efSXshine         let mut notifier_chain_guard = self.0.write();
160729a96efSXshine         return notifier_chain_guard.register(block, false);
161729a96efSXshine     }
162729a96efSXshine 
register_unique_prio( &mut self, block: Arc<dyn NotifierBlock<V, T>>, ) -> Result<(), SystemError>163729a96efSXshine     pub fn register_unique_prio(
164729a96efSXshine         &mut self,
16506d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
166729a96efSXshine     ) -> Result<(), SystemError> {
167729a96efSXshine         let mut notifier_chain_guard = self.0.write();
168729a96efSXshine         return notifier_chain_guard.register(block, true);
169729a96efSXshine     }
170729a96efSXshine 
unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>17106d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
172729a96efSXshine         let mut notifier_chain_guard = self.0.write();
173729a96efSXshine         return notifier_chain_guard.unregister(block);
174729a96efSXshine     }
175729a96efSXshine 
call_chain( &self, action: V, data: Option<&T>, nr_to_call: Option<usize>, ) -> (i32, usize)176729a96efSXshine     pub fn call_chain(
177729a96efSXshine         &self,
17806d5e247SLoGin         action: V,
179729a96efSXshine         data: Option<&T>,
180729a96efSXshine         nr_to_call: Option<usize>,
181729a96efSXshine     ) -> (i32, usize) {
182729a96efSXshine         let notifier_chain_guard = self.0.read();
183729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
184729a96efSXshine     }
185729a96efSXshine }
186729a96efSXshine 
187729a96efSXshine /// @brief 原始的通知链,由调用者自行考虑同步
18806d5e247SLoGin pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
189729a96efSXshine 
19006d5e247SLoGin impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
new() -> Self191729a96efSXshine     pub fn new() -> Self {
19206d5e247SLoGin         Self(NotifierChain::<V, T>::new())
193729a96efSXshine     }
194729a96efSXshine 
register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>19506d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
196729a96efSXshine         return self.0.register(block, false);
197729a96efSXshine     }
198729a96efSXshine 
unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError>19906d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
200729a96efSXshine         return self.0.unregister(block);
201729a96efSXshine     }
202729a96efSXshine 
call_chain( &self, action: V, data: Option<&T>, nr_to_call: Option<usize>, ) -> (i32, usize)203729a96efSXshine     pub fn call_chain(
204729a96efSXshine         &self,
20506d5e247SLoGin         action: V,
206729a96efSXshine         data: Option<&T>,
207729a96efSXshine         nr_to_call: Option<usize>,
208729a96efSXshine     ) -> (i32, usize) {
209729a96efSXshine         return self.0.call_chain(action, data, nr_to_call);
210729a96efSXshine     }
211729a96efSXshine }
212