TODO: Swith to use thread_local
(
class_name: Option<&str>, function_name: &str,
)
| 76 | |
| 77 | #[allow(static_mut_refs)] // TODO: Swith to use thread_local |
| 78 | pub fn select_plugin_hook( |
| 79 | class_name: Option<&str>, function_name: &str, |
| 80 | ) -> Option<(&'static BeforeExecuteHook, &'static AfterExecuteHook)> { |
| 81 | type HookMap = |
| 82 | HashMap<(Option<String>, String), Option<(Box<BeforeExecuteHook>, Box<AfterExecuteHook>)>>; |
| 83 | |
| 84 | static LOCK: Lazy<Mutex<()>> = Lazy::new(Default::default); |
| 85 | static mut HOOK_MAP: Lazy<HookMap> = Lazy::new(HashMap::new); |
| 86 | |
| 87 | let _guard = match LOCK.lock() { |
| 88 | Ok(guard) => guard, |
| 89 | Err(err) => { |
| 90 | error!(?err, "get lock failed"); |
| 91 | return None; |
| 92 | } |
| 93 | }; |
| 94 | unsafe { |
| 95 | HOOK_MAP |
| 96 | .entry((class_name.map(ToOwned::to_owned), function_name.to_owned())) |
| 97 | .or_insert_with(|| { |
| 98 | select_plugin(class_name, function_name) |
| 99 | .and_then(|plugin| plugin.hook(class_name, function_name)) |
| 100 | }) |
| 101 | .as_ref() |
| 102 | .map(|(before, after)| (before.deref(), after.deref())) |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | fn select_plugin(class_name: Option<&str>, function_name: &str) -> Option<&'static DynPlugin> { |
| 107 | let mut selected_plugin = None; |
no test coverage detected