1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use std::mem::transmute;
use std::thread;
use std::thread::JoinHandle;

pub struct ScopedThread {
    handle: Option<JoinHandle<()>>
}

impl ScopedThread {
    pub fn spawn<'scope, F>(f: F) -> ScopedThread
    where
        F: FnOnce() + Send + 'scope {
        // Transition from 'scope lifetime to 'static lifetime
        let f: Box<dyn FnOnce() + Send + 'scope> = Box::new(f);
        let f: Box<dyn FnOnce() + Send + 'static> = unsafe { transmute(f) };

        let handle = thread::spawn(f);
        ScopedThread {
            handle: Some(handle)
        }
    }
}

impl Drop for ScopedThread {
    fn drop(&mut self) {
        if let Some(handle) = self.handle.take() {
            handle.join().unwrap();
        }
    }
}