notifier.rs 6.3 KB

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