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