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