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