extern crate std;
use std::boxed::Box;
use crate::{Backdrop, BackdropStrategy};
pub struct ThreadStrategy();
impl<T: Send + 'static> BackdropStrategy<T> for ThreadStrategy {
#[inline]
fn execute(droppable: T) {
std::thread::spawn(|| {
core::mem::drop(droppable);
});
}
}
pub type ThreadBackdrop<T> = Backdrop<T, ThreadStrategy>;
pub struct GlobalTrashThreadHandle(std::sync::mpsc::SyncSender<Box<dyn Send>>);
use lazy_static::lazy_static;
lazy_static! {
pub static ref GLOBAL_TRASH_THREAD_HANDLE: GlobalTrashThreadHandle = {
let (send, recv) = std::sync::mpsc::sync_channel(10);
std::thread::spawn(move || {
for droppable in recv {
core::mem::drop(droppable)
}
});
GlobalTrashThreadHandle(send)
};
}
pub struct GlobalTrashThreadStrategy();
impl<T: Send + 'static> BackdropStrategy<T> for GlobalTrashThreadStrategy {
#[inline]
fn execute(droppable: T) {
let handle = &GLOBAL_TRASH_THREAD_HANDLE;
let _ = handle.0.send(Box::new(droppable));
}
}
pub type GlobalTrashThreadBackdrop<T> = Backdrop<T, GlobalTrashThreadStrategy>;
lazy_static! {
static ref TRASH_THREAD_HANDLE: std::sync::RwLock<Option<std::sync::mpsc::SyncSender<Box<dyn Send>>>> = {
std::sync::RwLock::new(None)
};
}
pub struct TrashThreadStrategy();
impl TrashThreadStrategy {
pub fn with_trash_thread<R>(fun: impl FnOnce() -> R) -> R {
let (send, recv) = std::sync::mpsc::sync_channel(10);
let thread_handle = std::thread::spawn(move || {
for droppable in recv {
core::mem::drop(droppable)
}
});
let orig_handle = {
let mut handle = TRASH_THREAD_HANDLE.write().unwrap();
std::mem::replace(&mut *handle, Some(send))
};
let result = fun();
{
let mut handle = TRASH_THREAD_HANDLE.write().unwrap();
*handle = orig_handle;
};
thread_handle.join().expect("Could not join on trash thread");
result
}
}
impl<T: Send + 'static> BackdropStrategy<T> for TrashThreadStrategy {
#[inline]
fn execute(droppable: T) {
let handle = &TRASH_THREAD_HANDLE;
let _ = handle.read().unwrap().as_ref().expect("No trash thread was started").send(Box::new(droppable));
}
}
pub type TrashThreadBackdrop<T> = Backdrop<T, TrashThreadStrategy>;