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