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