xref: /DragonOS/kernel/src/libs/notifier.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
1 #![allow(dead_code)]
2 use core::fmt::Debug;
3 
4 use crate::{
5     kwarn,
6     libs::{rwlock::RwLock, spinlock::SpinLock},
7 };
8 use alloc::{sync::Arc, vec::Vec};
9 use system_error::SystemError;
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::ptr_eq(&block, 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.0.extract_if(|b| Arc::ptr_eq(&block, b));
69         match remove.count() {
70             0 => return Err(SystemError::ENOENT),
71             _ => return Ok(()),
72         }
73     }
74 
75     /// 通知链进行事件通知
76     ///
77     /// ## 参数
78     ///
79     /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数
80     ///
81     /// ## 返回
82     ///
83     /// (最后一次回调函数的返回值,回调次数)
84     ///
85     /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能
86     pub fn call_chain(
87         &self,
88         action: V,
89         data: Option<&T>,
90         nr_to_call: Option<usize>,
91     ) -> (i32, usize) {
92         let mut ret: i32 = 0;
93         let mut nr_calls: usize = 0;
94 
95         for b in self.0.iter() {
96             if nr_to_call.is_some_and(|x| nr_calls >= x) {
97                 break;
98             }
99             ret = b.notifier_call(action, data);
100             nr_calls += 1;
101         }
102         return (ret, nr_calls);
103     }
104 }
105 
106 /// @brief 原子的通知链,使用 SpinLock 进行同步
107 #[derive(Debug)]
108 pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>);
109 
110 impl<V: Clone + Copy, T> Default for AtomicNotifierChain<V, T> {
111     fn default() -> Self {
112         Self::new()
113     }
114 }
115 
116 impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> {
117     pub fn new() -> Self {
118         Self(SpinLock::new(NotifierChain::<V, T>::new()))
119     }
120 
121     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
122         let mut notifier_chain_guard = self.0.lock();
123         return notifier_chain_guard.register(block, false);
124     }
125 
126     pub fn register_unique_prio(
127         &mut self,
128         block: Arc<dyn NotifierBlock<V, T>>,
129     ) -> Result<(), SystemError> {
130         let mut notifier_chain_guard = self.0.lock();
131         return notifier_chain_guard.register(block, true);
132     }
133 
134     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
135         let mut notifier_chain_guard = self.0.lock();
136         return notifier_chain_guard.unregister(block);
137     }
138 
139     pub fn call_chain(
140         &self,
141         action: V,
142         data: Option<&T>,
143         nr_to_call: Option<usize>,
144     ) -> (i32, usize) {
145         let notifier_chain_guard = self.0.lock();
146         return notifier_chain_guard.call_chain(action, data, nr_to_call);
147     }
148 }
149 
150 /// @brief 可阻塞的通知链,使用 RwLock 进行同步
151 // TODO: 使用 semaphore 封装
152 #[derive(Debug)]
153 pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
154 
155 impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
156     pub fn new() -> Self {
157         Self(RwLock::new(NotifierChain::<V, T>::new()))
158     }
159 
160     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
161         let mut notifier_chain_guard = self.0.write();
162         return notifier_chain_guard.register(block, false);
163     }
164 
165     pub fn register_unique_prio(
166         &mut self,
167         block: Arc<dyn NotifierBlock<V, T>>,
168     ) -> Result<(), SystemError> {
169         let mut notifier_chain_guard = self.0.write();
170         return notifier_chain_guard.register(block, true);
171     }
172 
173     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
174         let mut notifier_chain_guard = self.0.write();
175         return notifier_chain_guard.unregister(block);
176     }
177 
178     pub fn call_chain(
179         &self,
180         action: V,
181         data: Option<&T>,
182         nr_to_call: Option<usize>,
183     ) -> (i32, usize) {
184         let notifier_chain_guard = self.0.read();
185         return notifier_chain_guard.call_chain(action, data, nr_to_call);
186     }
187 }
188 
189 /// @brief 原始的通知链,由调用者自行考虑同步
190 pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
191 
192 impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
193     pub fn new() -> Self {
194         Self(NotifierChain::<V, T>::new())
195     }
196 
197     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
198         return self.0.register(block, false);
199     }
200 
201     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
202         return self.0.unregister(block);
203     }
204 
205     pub fn call_chain(
206         &self,
207         action: V,
208         data: Option<&T>,
209         nr_to_call: Option<usize>,
210     ) -> (i32, usize) {
211         return self.0.call_chain(action, data, nr_to_call);
212     }
213 }
214