1
Fork 0

Simplify scoped_thread

Avoids a bunch of manual pointer manipulation.
This commit is contained in:
Mark Rousskov 2021-09-19 14:02:38 -04:00
parent 0132f8258a
commit 0222556c07
2 changed files with 6 additions and 19 deletions

View file

@ -1,6 +1,7 @@
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(internal_output_capture)] #![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(nll)] #![feature(nll)]
#![feature(once_cell)] #![feature(once_cell)]
#![recursion_limit = "256"] #![recursion_limit = "256"]

View file

@ -115,25 +115,11 @@ fn get_stack_size() -> Option<usize> {
/// for `'static` bounds. /// for `'static` bounds.
#[cfg(not(parallel_compiler))] #[cfg(not(parallel_compiler))]
pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R { pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
struct Ptr(*mut ()); // SAFETY: join() is called immediately, so any closure captures are still
unsafe impl Send for Ptr {} // alive.
unsafe impl Sync for Ptr {} match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
Ok(v) => v,
let mut f = Some(f); Err(e) => panic::resume_unwind(e),
let run = Ptr(&mut f as *mut _ as *mut ());
let mut result = None;
let result_ptr = Ptr(&mut result as *mut _ as *mut ());
let thread = cfg.spawn(move || {
let _ = (&run, &result_ptr);
let run = unsafe { (*(run.0 as *mut Option<F>)).take().unwrap() };
let result = unsafe { &mut *(result_ptr.0 as *mut Option<R>) };
*result = Some(run());
});
match thread.unwrap().join() {
Ok(()) => result.unwrap(),
Err(p) => panic::resume_unwind(p),
} }
} }