notifier.rs 6.3 KB

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