use std::sync::{Arc,Weak,Mutex};
use std::marker;
pub trait InitCleanup {
fn init();
fn cleanup();
}
pub struct InitHandle<T: InitCleanup>(marker::PhantomData<T>);
impl <T: InitCleanup> InitHandle<T> {
pub fn new_global() -> GlobalInitHandle<T> {
Mutex::new(None)
}
pub fn from_global(handle: &Mutex<Option<Weak<InitHandle<T>>>>) -> LocalInitHandle<T> {
let mut handle = handle.lock().unwrap();
handle.as_ref()
.and_then(Weak::upgrade)
.unwrap_or_else(|| {
let new_handle = Arc::new(InitHandle(marker::PhantomData));
*handle = Some(Arc::downgrade(&new_handle));
T::init();
new_handle
})
}
}
impl <T: InitCleanup> Drop for InitHandle<T> {
fn drop(&mut self) {
T::cleanup()
}
}
pub type GlobalInitHandle<T> = Mutex<Option<Weak<InitHandle<T>>>>;
pub type LocalInitHandle<T> = Arc<InitHandle<T>>;