1 #![allow(dead_code)] 2 use core::fmt::Debug; 3 4 use crate::libs::{rwlock::RwLock, spinlock::SpinLock}; 5 use alloc::{sync::Arc, vec::Vec}; 6 use log::warn; 7 use system_error::SystemError; 8 9 /// @brief 通知链节点 10 pub trait NotifierBlock<V: Clone + Copy, T>: Debug + Send + Sync { 11 /// @brief 通知链中注册的回调函数类型 12 fn notifier_call(&self, action: V, data: Option<&T>) -> i32; 13 /// @brief 通知链节点的优先级 14 fn priority(&self) -> i32; 15 } 16 17 /// @brief 通知链 18 // TODO: 考虑使用红黑树封装 19 #[derive(Debug)] 20 struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>); 21 22 impl<V: Clone + Copy, T> NotifierChain<V, T> { 23 pub fn new() -> Self { 24 Self(vec![]) 25 } 26 27 /// @brief 将节点注册到通知链 28 /// @param unique_priority 检查通知链中优先级的唯一性 29 pub fn register( 30 &mut self, 31 block: Arc<dyn NotifierBlock<V, T>>, 32 unique_priority: bool, 33 ) -> Result<(), SystemError> { 34 let mut index: usize = 0; 35 36 // 在 notifier chain中寻找第一个优先级比要插入块低的块 37 for b in self.0.iter() { 38 // 判断之前是否已经注册过该节点 39 if Arc::ptr_eq(&block, b) { 40 warn!( 41 "notifier callback {:?} already registered", 42 Arc::as_ptr(&block) 43 ); 44 return Err(SystemError::EEXIST); 45 } 46 47 if block.priority() > b.priority() { 48 break; 49 } 50 51 // 优先级唯一性检测 52 if block.priority() == b.priority() && unique_priority { 53 return Err(SystemError::EBUSY); 54 } 55 56 index += 1; 57 } 58 59 // 插入 notifier chain 60 self.0.insert(index, block); 61 return Ok(()); 62 } 63 64 /// @brief 在通知链中取消注册节点 65 pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 66 let remove = self.0.extract_if(|b| Arc::ptr_eq(&block, b)); 67 match remove.count() { 68 0 => return Err(SystemError::ENOENT), 69 _ => return Ok(()), 70 } 71 } 72 73 /// 通知链进行事件通知 74 /// 75 /// ## 参数 76 /// 77 /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数 78 /// 79 /// ## 返回 80 /// 81 /// (最后一次回调函数的返回值,回调次数) 82 /// 83 /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能 84 pub fn call_chain( 85 &self, 86 action: V, 87 data: Option<&T>, 88 nr_to_call: Option<usize>, 89 ) -> (i32, usize) { 90 let mut ret: i32 = 0; 91 let mut nr_calls: usize = 0; 92 93 for b in self.0.iter() { 94 if nr_to_call.is_some_and(|x| nr_calls >= x) { 95 break; 96 } 97 ret = b.notifier_call(action, data); 98 nr_calls += 1; 99 } 100 return (ret, nr_calls); 101 } 102 } 103 104 /// @brief 原子的通知链,使用 SpinLock 进行同步 105 #[derive(Debug)] 106 pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>); 107 108 impl<V: Clone + Copy, T> Default for AtomicNotifierChain<V, T> { 109 fn default() -> Self { 110 Self::new() 111 } 112 } 113 114 impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> { 115 pub fn new() -> Self { 116 Self(SpinLock::new(NotifierChain::<V, T>::new())) 117 } 118 119 pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 120 let mut notifier_chain_guard = self.0.lock(); 121 return notifier_chain_guard.register(block, false); 122 } 123 124 pub fn register_unique_prio( 125 &mut self, 126 block: Arc<dyn NotifierBlock<V, T>>, 127 ) -> Result<(), SystemError> { 128 let mut notifier_chain_guard = self.0.lock(); 129 return notifier_chain_guard.register(block, true); 130 } 131 132 pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 133 let mut notifier_chain_guard = self.0.lock(); 134 return notifier_chain_guard.unregister(block); 135 } 136 137 pub fn call_chain( 138 &self, 139 action: V, 140 data: Option<&T>, 141 nr_to_call: Option<usize>, 142 ) -> (i32, usize) { 143 let notifier_chain_guard = self.0.lock(); 144 return notifier_chain_guard.call_chain(action, data, nr_to_call); 145 } 146 } 147 148 /// @brief 可阻塞的通知链,使用 RwLock 进行同步 149 // TODO: 使用 semaphore 封装 150 #[derive(Debug)] 151 pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>); 152 153 impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> { 154 pub fn new() -> Self { 155 Self(RwLock::new(NotifierChain::<V, T>::new())) 156 } 157 158 pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 159 let mut notifier_chain_guard = self.0.write(); 160 return notifier_chain_guard.register(block, false); 161 } 162 163 pub fn register_unique_prio( 164 &mut self, 165 block: Arc<dyn NotifierBlock<V, T>>, 166 ) -> Result<(), SystemError> { 167 let mut notifier_chain_guard = self.0.write(); 168 return notifier_chain_guard.register(block, true); 169 } 170 171 pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 172 let mut notifier_chain_guard = self.0.write(); 173 return notifier_chain_guard.unregister(block); 174 } 175 176 pub fn call_chain( 177 &self, 178 action: V, 179 data: Option<&T>, 180 nr_to_call: Option<usize>, 181 ) -> (i32, usize) { 182 let notifier_chain_guard = self.0.read(); 183 return notifier_chain_guard.call_chain(action, data, nr_to_call); 184 } 185 } 186 187 /// @brief 原始的通知链,由调用者自行考虑同步 188 pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>); 189 190 impl<V: Clone + Copy, T> RawNotifierChain<V, T> { 191 pub fn new() -> Self { 192 Self(NotifierChain::<V, T>::new()) 193 } 194 195 pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 196 return self.0.register(block, false); 197 } 198 199 pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 200 return self.0.unregister(block); 201 } 202 203 pub fn call_chain( 204 &self, 205 action: V, 206 data: Option<&T>, 207 nr_to_call: Option<usize>, 208 ) -> (i32, usize) { 209 return self.0.call_chain(action, data, nr_to_call); 210 } 211 } 212