use crate::core::detector;
use crate::core::types::get_current_thread_id;
pub use std::thread::{
AccessError, JoinHandle, LocalKey, Result, Scope, ScopedJoinHandle, Thread, ThreadId,
available_parallelism, current, panicking, park, park_timeout, sleep, yield_now,
};
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
Builder::new().spawn(f).unwrap()
}
pub struct Builder {
inner: std::thread::Builder,
}
impl Builder {
pub fn new() -> Builder {
Builder {
inner: std::thread::Builder::new(),
}
}
pub fn name(mut self, name: String) -> Builder {
self.inner = self.inner.name(name);
self
}
pub fn stack_size(mut self, size: usize) -> Builder {
self.inner = self.inner.stack_size(size);
self
}
pub fn spawn<F, T>(self, f: F) -> std::io::Result<JoinHandle<T>>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
let parent_tid = get_current_thread_id();
self.inner.spawn(move || {
let tid = get_current_thread_id();
detector::thread::spawn_thread(tid, Some(parent_tid));
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f));
detector::thread::exit_thread(tid);
match result {
Ok(val) => val,
Err(payload) => std::panic::resume_unwind(payload),
}
})
}
pub fn spawn_scoped<'scope, 'env, F, T>(
self,
scope: &'scope Scope<'scope, 'env>,
f: F,
) -> std::io::Result<ScopedJoinHandle<'scope, T>>
where
F: FnOnce() -> T + Send + 'scope,
T: Send + 'scope,
{
let parent_tid = get_current_thread_id();
self.inner.spawn_scoped(scope, move || {
let tid = get_current_thread_id();
detector::thread::spawn_thread(tid, Some(parent_tid));
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f));
detector::thread::exit_thread(tid);
match result {
Ok(val) => val,
Err(payload) => std::panic::resume_unwind(payload),
}
})
}
}
impl Default for Builder {
fn default() -> Self {
Self::new()
}
}
pub fn scope<'env, F, T>(f: F) -> T
where
F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T,
{
std::thread::scope(f)
}