mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-19 19:23:10 +00:00
Simplify scoped_thread
Avoids a bunch of manual pointer manipulation.
This commit is contained in:
parent
0132f8258a
commit
0222556c07
@ -1,6 +1,7 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(internal_output_capture)]
|
||||
#![feature(thread_spawn_unchecked)]
|
||||
#![feature(nll)]
|
||||
#![feature(once_cell)]
|
||||
#![recursion_limit = "256"]
|
||||
|
@ -115,25 +115,11 @@ fn get_stack_size() -> Option<usize> {
|
||||
/// for `'static` bounds.
|
||||
#[cfg(not(parallel_compiler))]
|
||||
pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
|
||||
struct Ptr(*mut ());
|
||||
unsafe impl Send for Ptr {}
|
||||
unsafe impl Sync for Ptr {}
|
||||
|
||||
let mut f = Some(f);
|
||||
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),
|
||||
// SAFETY: join() is called immediately, so any closure captures are still
|
||||
// alive.
|
||||
match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic::resume_unwind(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user