126887c63SLoGin #![allow(dead_code)] 206d5e247SLoGin use core::fmt::Debug; 306d5e247SLoGin 4729a96efSXshine use crate::{ 5729a96efSXshine kwarn, 6729a96efSXshine libs::{rwlock::RwLock, spinlock::SpinLock}, 7729a96efSXshine }; 8729a96efSXshine use alloc::{sync::Arc, vec::Vec}; 9*91e9d4abSLoGin use system_error::SystemError; 10729a96efSXshine 11729a96efSXshine /// @brief 通知链节点 1206d5e247SLoGin pub trait NotifierBlock<V: Clone + Copy, T>: Debug + Send + Sync { 13729a96efSXshine /// @brief 通知链中注册的回调函数类型 1406d5e247SLoGin fn notifier_call(&self, action: V, data: Option<&T>) -> i32; 15729a96efSXshine /// @brief 通知链节点的优先级 16729a96efSXshine fn priority(&self) -> i32; 17729a96efSXshine } 18729a96efSXshine 19729a96efSXshine /// @brief 通知链 20729a96efSXshine // TODO: 考虑使用红黑树封装 2106d5e247SLoGin #[derive(Debug)] 2206d5e247SLoGin struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>); 23729a96efSXshine 2406d5e247SLoGin impl<V: Clone + Copy, T> NotifierChain<V, T> { 25729a96efSXshine pub fn new() -> Self { 26729a96efSXshine Self(vec![]) 27729a96efSXshine } 28729a96efSXshine 29729a96efSXshine /// @brief 将节点注册到通知链 30729a96efSXshine /// @param unique_priority 检查通知链中优先级的唯一性 31729a96efSXshine pub fn register( 32729a96efSXshine &mut self, 3306d5e247SLoGin block: Arc<dyn NotifierBlock<V, T>>, 34729a96efSXshine unique_priority: bool, 35729a96efSXshine ) -> Result<(), SystemError> { 36729a96efSXshine let mut index: usize = 0; 37729a96efSXshine 38729a96efSXshine // 在 notifier chain中寻找第一个优先级比要插入块低的块 39729a96efSXshine for b in self.0.iter() { 40729a96efSXshine // 判断之前是否已经注册过该节点 41729a96efSXshine if Arc::as_ptr(&block) == Arc::as_ptr(b) { 42729a96efSXshine kwarn!( 43729a96efSXshine "notifier callback {:?} already registered", 44729a96efSXshine Arc::as_ptr(&block) 45729a96efSXshine ); 46729a96efSXshine return Err(SystemError::EEXIST); 47729a96efSXshine } 48729a96efSXshine 49729a96efSXshine if block.priority() > b.priority() { 50729a96efSXshine break; 51729a96efSXshine } 52729a96efSXshine 53729a96efSXshine // 优先级唯一性检测 54729a96efSXshine if block.priority() == b.priority() && unique_priority { 55729a96efSXshine return Err(SystemError::EBUSY); 56729a96efSXshine } 57729a96efSXshine 58729a96efSXshine index += 1; 59729a96efSXshine } 60729a96efSXshine 61729a96efSXshine // 插入 notifier chain 62729a96efSXshine self.0.insert(index, block); 63729a96efSXshine return Ok(()); 64729a96efSXshine } 65729a96efSXshine 66729a96efSXshine /// @brief 在通知链中取消注册节点 6706d5e247SLoGin pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 681a72a751SLoGin let remove = self.0.extract_if(|b| Arc::as_ptr(&block) == Arc::as_ptr(b)); 69729a96efSXshine match remove.count() { 70729a96efSXshine 0 => return Err(SystemError::ENOENT), 71729a96efSXshine _ => return Ok(()), 72729a96efSXshine } 73729a96efSXshine } 74729a96efSXshine 7506d5e247SLoGin /// 通知链进行事件通知 7606d5e247SLoGin /// 7706d5e247SLoGin /// ## 参数 7806d5e247SLoGin /// 7906d5e247SLoGin /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数 8006d5e247SLoGin /// 8106d5e247SLoGin /// ## 返回 8206d5e247SLoGin /// 8306d5e247SLoGin /// (最后一次回调函数的返回值,回调次数) 8406d5e247SLoGin /// 8506d5e247SLoGin /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能 86729a96efSXshine pub fn call_chain( 87729a96efSXshine &self, 8806d5e247SLoGin action: V, 89729a96efSXshine data: Option<&T>, 90729a96efSXshine nr_to_call: Option<usize>, 91729a96efSXshine ) -> (i32, usize) { 92729a96efSXshine let mut ret: i32 = 0; 93729a96efSXshine let mut nr_calls: usize = 0; 94729a96efSXshine 95729a96efSXshine for b in self.0.iter() { 96729a96efSXshine if nr_to_call.is_some_and(|x| nr_calls >= x) { 97729a96efSXshine break; 98729a96efSXshine } 99729a96efSXshine ret = b.notifier_call(action, data); 100729a96efSXshine nr_calls += 1; 101729a96efSXshine } 102729a96efSXshine return (ret, nr_calls); 103729a96efSXshine } 104729a96efSXshine } 105729a96efSXshine 106729a96efSXshine /// @brief 原子的通知链,使用 SpinLock 进行同步 10706d5e247SLoGin #[derive(Debug)] 10806d5e247SLoGin pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>); 109729a96efSXshine 11006d5e247SLoGin impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> { 111729a96efSXshine pub fn new() -> Self { 11206d5e247SLoGin Self(SpinLock::new(NotifierChain::<V, T>::new())) 113729a96efSXshine } 114729a96efSXshine 11506d5e247SLoGin pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 116729a96efSXshine let mut notifier_chain_guard = self.0.lock(); 117729a96efSXshine return notifier_chain_guard.register(block, false); 118729a96efSXshine } 119729a96efSXshine 120729a96efSXshine pub fn register_unique_prio( 121729a96efSXshine &mut self, 12206d5e247SLoGin block: Arc<dyn NotifierBlock<V, T>>, 123729a96efSXshine ) -> Result<(), SystemError> { 124729a96efSXshine let mut notifier_chain_guard = self.0.lock(); 125729a96efSXshine return notifier_chain_guard.register(block, true); 126729a96efSXshine } 127729a96efSXshine 12806d5e247SLoGin pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 129729a96efSXshine let mut notifier_chain_guard = self.0.lock(); 130729a96efSXshine return notifier_chain_guard.unregister(block); 131729a96efSXshine } 132729a96efSXshine 133729a96efSXshine pub fn call_chain( 134729a96efSXshine &self, 13506d5e247SLoGin action: V, 136729a96efSXshine data: Option<&T>, 137729a96efSXshine nr_to_call: Option<usize>, 138729a96efSXshine ) -> (i32, usize) { 139729a96efSXshine let notifier_chain_guard = self.0.lock(); 140729a96efSXshine return notifier_chain_guard.call_chain(action, data, nr_to_call); 141729a96efSXshine } 142729a96efSXshine } 143729a96efSXshine 144729a96efSXshine /// @brief 可阻塞的通知链,使用 RwLock 进行同步 145729a96efSXshine // TODO: 使用 semaphore 封装 14606d5e247SLoGin #[derive(Debug)] 14706d5e247SLoGin pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>); 148729a96efSXshine 14906d5e247SLoGin impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> { 150729a96efSXshine pub fn new() -> Self { 15106d5e247SLoGin Self(RwLock::new(NotifierChain::<V, T>::new())) 152729a96efSXshine } 153729a96efSXshine 15406d5e247SLoGin pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 155729a96efSXshine let mut notifier_chain_guard = self.0.write(); 156729a96efSXshine return notifier_chain_guard.register(block, false); 157729a96efSXshine } 158729a96efSXshine 159729a96efSXshine pub fn register_unique_prio( 160729a96efSXshine &mut self, 16106d5e247SLoGin block: Arc<dyn NotifierBlock<V, T>>, 162729a96efSXshine ) -> Result<(), SystemError> { 163729a96efSXshine let mut notifier_chain_guard = self.0.write(); 164729a96efSXshine return notifier_chain_guard.register(block, true); 165729a96efSXshine } 166729a96efSXshine 16706d5e247SLoGin pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 168729a96efSXshine let mut notifier_chain_guard = self.0.write(); 169729a96efSXshine return notifier_chain_guard.unregister(block); 170729a96efSXshine } 171729a96efSXshine 172729a96efSXshine pub fn call_chain( 173729a96efSXshine &self, 17406d5e247SLoGin action: V, 175729a96efSXshine data: Option<&T>, 176729a96efSXshine nr_to_call: Option<usize>, 177729a96efSXshine ) -> (i32, usize) { 178729a96efSXshine let notifier_chain_guard = self.0.read(); 179729a96efSXshine return notifier_chain_guard.call_chain(action, data, nr_to_call); 180729a96efSXshine } 181729a96efSXshine } 182729a96efSXshine 183729a96efSXshine /// @brief 原始的通知链,由调用者自行考虑同步 18406d5e247SLoGin pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>); 185729a96efSXshine 18606d5e247SLoGin impl<V: Clone + Copy, T> RawNotifierChain<V, T> { 187729a96efSXshine pub fn new() -> Self { 18806d5e247SLoGin Self(NotifierChain::<V, T>::new()) 189729a96efSXshine } 190729a96efSXshine 19106d5e247SLoGin pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 192729a96efSXshine return self.0.register(block, false); 193729a96efSXshine } 194729a96efSXshine 19506d5e247SLoGin pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> { 196729a96efSXshine return self.0.unregister(block); 197729a96efSXshine } 198729a96efSXshine 199729a96efSXshine pub fn call_chain( 200729a96efSXshine &self, 20106d5e247SLoGin action: V, 202729a96efSXshine data: Option<&T>, 203729a96efSXshine nr_to_call: Option<usize>, 204729a96efSXshine ) -> (i32, usize) { 205729a96efSXshine return self.0.call_chain(action, data, nr_to_call); 206729a96efSXshine } 207729a96efSXshine } 208