ctru/services/
reference.rs1use crate::Error;
2use std::sync::{Mutex, MutexGuard, TryLockError};
3
4pub(crate) struct ServiceReference {
5 _guard: MutexGuard<'static, ()>,
6 close: Box<dyn Fn() + Send + Sync>,
7}
8
9impl ServiceReference {
10 pub fn new<S, E>(counter: &'static Mutex<()>, start: S, close: E) -> crate::Result<Self>
11 where
12 S: FnOnce() -> crate::Result<()>,
13 E: Fn() + Send + Sync + 'static,
14 {
15 let _guard = match counter.try_lock() {
16 Ok(lock) => lock,
17 Err(e) => match e {
18 TryLockError::Poisoned(guard) => {
19 close();
24
25 guard.into_inner()
26 }
27 TryLockError::WouldBlock => return Err(Error::ServiceAlreadyActive),
28 },
29 };
30
31 start()?;
32
33 Ok(Self {
34 _guard,
35 close: Box::new(close),
36 })
37 }
38}
39
40impl Drop for ServiceReference {
41 fn drop(&mut self) {
42 (self.close)();
43 }
44}