borrowed_thread/
lib.rs

1#![feature(thread_spawn_unchecked)]
2#![feature(test)]
3
4use std::thread;
5use std::marker::PhantomData;
6use std::io;
7
8struct JoinFlag {
9    is_joined: bool,
10}
11
12impl JoinFlag {
13    fn new() -> Self {
14        Self {
15            is_joined: false,
16        }
17    }
18
19    fn set_join(mut self) {
20        self.is_joined = true;
21    }
22}
23
24impl Drop for JoinFlag {
25    #[inline]
26    fn drop(&mut self) {
27        if !self.is_joined {
28            panic!("handle must be join before dropped")
29        }
30    }
31}
32
33pub struct BorrowedJoinHandle<'b, T> {
34    inner: thread::JoinHandle<T>,
35    join_flag: JoinFlag,
36    _marker: PhantomData<&'b ()>,
37}
38
39impl<'b, T> From<thread::JoinHandle<T>> for BorrowedJoinHandle<'b, T> {
40
41    #[inline]
42    fn from(handle: thread::JoinHandle<T>) -> Self {
43        Self::new(handle)
44    }
45}
46
47impl<'b, T> BorrowedJoinHandle<'b, T> {
48
49    #[inline]
50    fn new(inner: thread::JoinHandle<T>) -> Self {
51        Self {
52            inner,
53            join_flag: JoinFlag::new(),
54            _marker: PhantomData,
55        }
56    }
57
58    #[inline]
59    pub fn thread(&self) -> &thread::Thread {
60        self.inner.thread()
61    }
62
63    #[inline]
64    pub fn join(self) -> thread::Result<T> {
65        self.join_flag.set_join();
66        self.inner.join()
67    }
68}
69
70#[inline]
71pub fn spawn_with<'b, F, T>(builder: thread::Builder, f: F) -> io::Result<BorrowedJoinHandle<'b, T>>
72    where
73        F: FnOnce() -> T,
74        F: Send + 'b,
75        T: Send + 'b, {
76    unsafe {
77        match builder.spawn_unchecked(f) {
78            Ok(handle) => Ok(handle.into()),
79            Err(err) => Err(err),
80        }
81    }
82}
83
84#[inline]
85pub fn spawn<'b, F, T>(f: F) -> BorrowedJoinHandle<'b, T>
86where
87    F: FnOnce() -> T,
88    F: Send + 'b,
89    T: Send + 'b,
90{
91    spawn_with(thread::Builder::new(), f).unwrap()
92}
93
94#[cfg(test)]
95mod tests;
96
97#[cfg(test)]
98mod bench;