xref: /DragonOS/kernel/src/libs/notifier.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
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::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.0.extract_if(|b| Arc::as_ptr(&block) == Arc::as_ptr(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> AtomicNotifierChain<V, T> {
111     pub fn new() -> Self {
112         Self(SpinLock::new(NotifierChain::<V, T>::new()))
113     }
114 
115     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
116         let mut notifier_chain_guard = self.0.lock();
117         return notifier_chain_guard.register(block, false);
118     }
119 
120     pub fn register_unique_prio(
121         &mut self,
122         block: Arc<dyn NotifierBlock<V, T>>,
123     ) -> Result<(), SystemError> {
124         let mut notifier_chain_guard = self.0.lock();
125         return notifier_chain_guard.register(block, true);
126     }
127 
128     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
129         let mut notifier_chain_guard = self.0.lock();
130         return notifier_chain_guard.unregister(block);
131     }
132 
133     pub fn call_chain(
134         &self,
135         action: V,
136         data: Option<&T>,
137         nr_to_call: Option<usize>,
138     ) -> (i32, usize) {
139         let notifier_chain_guard = self.0.lock();
140         return notifier_chain_guard.call_chain(action, data, nr_to_call);
141     }
142 }
143 
144 /// @brief 可阻塞的通知链,使用 RwLock 进行同步
145 // TODO: 使用 semaphore 封装
146 #[derive(Debug)]
147 pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
148 
149 impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
150     pub fn new() -> Self {
151         Self(RwLock::new(NotifierChain::<V, T>::new()))
152     }
153 
154     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
155         let mut notifier_chain_guard = self.0.write();
156         return notifier_chain_guard.register(block, false);
157     }
158 
159     pub fn register_unique_prio(
160         &mut self,
161         block: Arc<dyn NotifierBlock<V, T>>,
162     ) -> Result<(), SystemError> {
163         let mut notifier_chain_guard = self.0.write();
164         return notifier_chain_guard.register(block, true);
165     }
166 
167     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
168         let mut notifier_chain_guard = self.0.write();
169         return notifier_chain_guard.unregister(block);
170     }
171 
172     pub fn call_chain(
173         &self,
174         action: V,
175         data: Option<&T>,
176         nr_to_call: Option<usize>,
177     ) -> (i32, usize) {
178         let notifier_chain_guard = self.0.read();
179         return notifier_chain_guard.call_chain(action, data, nr_to_call);
180     }
181 }
182 
183 /// @brief 原始的通知链,由调用者自行考虑同步
184 pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
185 
186 impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
187     pub fn new() -> Self {
188         Self(NotifierChain::<V, T>::new())
189     }
190 
191     pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
192         return self.0.register(block, false);
193     }
194 
195     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
196         return self.0.unregister(block);
197     }
198 
199     pub fn call_chain(
200         &self,
201         action: V,
202         data: Option<&T>,
203         nr_to_call: Option<usize>,
204     ) -> (i32, usize) {
205         return self.0.call_chain(action, data, nr_to_call);
206     }
207 }
208