xref: /DragonOS/kernel/src/libs/notifier.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
126887c63SLoGin #![allow(dead_code)]
206d5e247SLoGin use core::fmt::Debug;
306d5e247SLoGin 
4729a96efSXshine use crate::{
5729a96efSXshine     kwarn,
6729a96efSXshine     libs::{rwlock::RwLock, spinlock::SpinLock},
7729a96efSXshine };
8729a96efSXshine use alloc::{sync::Arc, vec::Vec};
9*91e9d4abSLoGin use system_error::SystemError;
10729a96efSXshine 
11729a96efSXshine /// @brief 通知链节点
1206d5e247SLoGin pub trait NotifierBlock<V: Clone + Copy, T>: Debug + Send + Sync {
13729a96efSXshine     /// @brief 通知链中注册的回调函数类型
1406d5e247SLoGin     fn notifier_call(&self, action: V, data: Option<&T>) -> i32;
15729a96efSXshine     /// @brief 通知链节点的优先级
16729a96efSXshine     fn priority(&self) -> i32;
17729a96efSXshine }
18729a96efSXshine 
19729a96efSXshine /// @brief 通知链
20729a96efSXshine // TODO: 考虑使用红黑树封装
2106d5e247SLoGin #[derive(Debug)]
2206d5e247SLoGin struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>);
23729a96efSXshine 
2406d5e247SLoGin impl<V: Clone + Copy, T> NotifierChain<V, T> {
25729a96efSXshine     pub fn new() -> Self {
26729a96efSXshine         Self(vec![])
27729a96efSXshine     }
28729a96efSXshine 
29729a96efSXshine     /// @brief 将节点注册到通知链
30729a96efSXshine     /// @param unique_priority 检查通知链中优先级的唯一性
31729a96efSXshine     pub fn register(
32729a96efSXshine         &mut self,
3306d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
34729a96efSXshine         unique_priority: bool,
35729a96efSXshine     ) -> Result<(), SystemError> {
36729a96efSXshine         let mut index: usize = 0;
37729a96efSXshine 
38729a96efSXshine         // 在 notifier chain中寻找第一个优先级比要插入块低的块
39729a96efSXshine         for b in self.0.iter() {
40729a96efSXshine             // 判断之前是否已经注册过该节点
41729a96efSXshine             if Arc::as_ptr(&block) == Arc::as_ptr(b) {
42729a96efSXshine                 kwarn!(
43729a96efSXshine                     "notifier callback {:?} already registered",
44729a96efSXshine                     Arc::as_ptr(&block)
45729a96efSXshine                 );
46729a96efSXshine                 return Err(SystemError::EEXIST);
47729a96efSXshine             }
48729a96efSXshine 
49729a96efSXshine             if block.priority() > b.priority() {
50729a96efSXshine                 break;
51729a96efSXshine             }
52729a96efSXshine 
53729a96efSXshine             // 优先级唯一性检测
54729a96efSXshine             if block.priority() == b.priority() && unique_priority {
55729a96efSXshine                 return Err(SystemError::EBUSY);
56729a96efSXshine             }
57729a96efSXshine 
58729a96efSXshine             index += 1;
59729a96efSXshine         }
60729a96efSXshine 
61729a96efSXshine         // 插入 notifier chain
62729a96efSXshine         self.0.insert(index, block);
63729a96efSXshine         return Ok(());
64729a96efSXshine     }
65729a96efSXshine 
66729a96efSXshine     /// @brief 在通知链中取消注册节点
6706d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
681a72a751SLoGin         let remove = self.0.extract_if(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
69729a96efSXshine         match remove.count() {
70729a96efSXshine             0 => return Err(SystemError::ENOENT),
71729a96efSXshine             _ => return Ok(()),
72729a96efSXshine         }
73729a96efSXshine     }
74729a96efSXshine 
7506d5e247SLoGin     /// 通知链进行事件通知
7606d5e247SLoGin     ///
7706d5e247SLoGin     /// ## 参数
7806d5e247SLoGin     ///
7906d5e247SLoGin     /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数
8006d5e247SLoGin     ///
8106d5e247SLoGin     /// ## 返回
8206d5e247SLoGin     ///
8306d5e247SLoGin     /// (最后一次回调函数的返回值,回调次数)
8406d5e247SLoGin     ///
8506d5e247SLoGin     /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能
86729a96efSXshine     pub fn call_chain(
87729a96efSXshine         &self,
8806d5e247SLoGin         action: V,
89729a96efSXshine         data: Option<&T>,
90729a96efSXshine         nr_to_call: Option<usize>,
91729a96efSXshine     ) -> (i32, usize) {
92729a96efSXshine         let mut ret: i32 = 0;
93729a96efSXshine         let mut nr_calls: usize = 0;
94729a96efSXshine 
95729a96efSXshine         for b in self.0.iter() {
96729a96efSXshine             if nr_to_call.is_some_and(|x| nr_calls >= x) {
97729a96efSXshine                 break;
98729a96efSXshine             }
99729a96efSXshine             ret = b.notifier_call(action, data);
100729a96efSXshine             nr_calls += 1;
101729a96efSXshine         }
102729a96efSXshine         return (ret, nr_calls);
103729a96efSXshine     }
104729a96efSXshine }
105729a96efSXshine 
106729a96efSXshine /// @brief 原子的通知链,使用 SpinLock 进行同步
10706d5e247SLoGin #[derive(Debug)]
10806d5e247SLoGin pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>);
109729a96efSXshine 
11006d5e247SLoGin impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> {
111729a96efSXshine     pub fn new() -> Self {
11206d5e247SLoGin         Self(SpinLock::new(NotifierChain::<V, T>::new()))
113729a96efSXshine     }
114729a96efSXshine 
11506d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
116729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
117729a96efSXshine         return notifier_chain_guard.register(block, false);
118729a96efSXshine     }
119729a96efSXshine 
120729a96efSXshine     pub fn register_unique_prio(
121729a96efSXshine         &mut self,
12206d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
123729a96efSXshine     ) -> Result<(), SystemError> {
124729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
125729a96efSXshine         return notifier_chain_guard.register(block, true);
126729a96efSXshine     }
127729a96efSXshine 
12806d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
129729a96efSXshine         let mut notifier_chain_guard = self.0.lock();
130729a96efSXshine         return notifier_chain_guard.unregister(block);
131729a96efSXshine     }
132729a96efSXshine 
133729a96efSXshine     pub fn call_chain(
134729a96efSXshine         &self,
13506d5e247SLoGin         action: V,
136729a96efSXshine         data: Option<&T>,
137729a96efSXshine         nr_to_call: Option<usize>,
138729a96efSXshine     ) -> (i32, usize) {
139729a96efSXshine         let notifier_chain_guard = self.0.lock();
140729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
141729a96efSXshine     }
142729a96efSXshine }
143729a96efSXshine 
144729a96efSXshine /// @brief 可阻塞的通知链,使用 RwLock 进行同步
145729a96efSXshine // TODO: 使用 semaphore 封装
14606d5e247SLoGin #[derive(Debug)]
14706d5e247SLoGin pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
148729a96efSXshine 
14906d5e247SLoGin impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
150729a96efSXshine     pub fn new() -> Self {
15106d5e247SLoGin         Self(RwLock::new(NotifierChain::<V, T>::new()))
152729a96efSXshine     }
153729a96efSXshine 
15406d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
155729a96efSXshine         let mut notifier_chain_guard = self.0.write();
156729a96efSXshine         return notifier_chain_guard.register(block, false);
157729a96efSXshine     }
158729a96efSXshine 
159729a96efSXshine     pub fn register_unique_prio(
160729a96efSXshine         &mut self,
16106d5e247SLoGin         block: Arc<dyn NotifierBlock<V, T>>,
162729a96efSXshine     ) -> Result<(), SystemError> {
163729a96efSXshine         let mut notifier_chain_guard = self.0.write();
164729a96efSXshine         return notifier_chain_guard.register(block, true);
165729a96efSXshine     }
166729a96efSXshine 
16706d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
168729a96efSXshine         let mut notifier_chain_guard = self.0.write();
169729a96efSXshine         return notifier_chain_guard.unregister(block);
170729a96efSXshine     }
171729a96efSXshine 
172729a96efSXshine     pub fn call_chain(
173729a96efSXshine         &self,
17406d5e247SLoGin         action: V,
175729a96efSXshine         data: Option<&T>,
176729a96efSXshine         nr_to_call: Option<usize>,
177729a96efSXshine     ) -> (i32, usize) {
178729a96efSXshine         let notifier_chain_guard = self.0.read();
179729a96efSXshine         return notifier_chain_guard.call_chain(action, data, nr_to_call);
180729a96efSXshine     }
181729a96efSXshine }
182729a96efSXshine 
183729a96efSXshine /// @brief 原始的通知链,由调用者自行考虑同步
18406d5e247SLoGin pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
185729a96efSXshine 
18606d5e247SLoGin impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
187729a96efSXshine     pub fn new() -> Self {
18806d5e247SLoGin         Self(NotifierChain::<V, T>::new())
189729a96efSXshine     }
190729a96efSXshine 
19106d5e247SLoGin     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
192729a96efSXshine         return self.0.register(block, false);
193729a96efSXshine     }
194729a96efSXshine 
19506d5e247SLoGin     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
196729a96efSXshine         return self.0.unregister(block);
197729a96efSXshine     }
198729a96efSXshine 
199729a96efSXshine     pub fn call_chain(
200729a96efSXshine         &self,
20106d5e247SLoGin         action: V,
202729a96efSXshine         data: Option<&T>,
203729a96efSXshine         nr_to_call: Option<usize>,
204729a96efSXshine     ) -> (i32, usize) {
205729a96efSXshine         return self.0.call_chain(action, data, nr_to_call);
206729a96efSXshine     }
207729a96efSXshine }
208