Skip to content

Instantly share code, notes, and snippets.

@sonthonaxrk
Last active May 16, 2025 16:06
Show Gist options
  • Save sonthonaxrk/54823f23ce811a3df9b17c4718f06ad6 to your computer and use it in GitHub Desktop.
Save sonthonaxrk/54823f23ce811a3df9b17c4718f06ad6 to your computer and use it in GitHub Desktop.
use std::marker::PhantomData;
use std::thread::{sleep, spawn, JoinHandle};
use std::time::Duration;
#[derive(Default)]
pub struct ThreadScope<'thread> {
_marker: PhantomData<&'thread ()>,
joins: Vec<JoinHandle<()>>,
}
impl<'thread> ThreadScope<'thread> {
pub fn spawn<F>(&mut self, f: F)
where
F: FnOnce() + Send + 'thread,
{
let func: Box<dyn FnOnce() + Send + 'thread> = Box::new(f);
// Here we 'transmute' 'thread to 'static
let closure: Box<dyn FnOnce() + Send + 'static> = unsafe {
std::mem::transmute(func)
};
let handle = spawn(closure);
self.joins.push(handle);
}
}
impl<'thread> Drop for ThreadScope<'thread> {
fn drop(&mut self) {
for handle in self.joins.drain(..) {
handle.join().unwrap();
}
}
}
fn main() {
let val = String::from("hello");
let val_ref = val.as_str();
let mut scope = ThreadScope::default();
scope.spawn(|| {
println!("{:?}", &val_ref);
});
scope.spawn(|| {
println!("{:?}", &val_ref);
});
drop(scope);
drop(val);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment