diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 56628a4c7545e..ed6921bcb4235 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -38,7 +38,6 @@ pub mod net; pub mod poison; pub mod remutex; pub mod rwlock; -pub mod thread; pub mod thread_info; pub mod thread_local; pub mod unwind; diff --git a/src/libstd/sys/common/thread.rs b/src/libstd/sys/common/thread.rs deleted file mode 100644 index 16f4f01bf39fe..0000000000000 --- a/src/libstd/sys/common/thread.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use prelude::v1::*; - -use alloc::boxed::FnBox; -use libc; -use sys::stack_overflow; - -pub unsafe fn start_thread(main: *mut libc::c_void) { - // Next, set up our stack overflow handler which may get triggered if we run - // out of stack. - let _handler = stack_overflow::Handler::new(); - - // Finally, let's run some code. - Box::from_raw(main as *mut Box)() -} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 793a2ecae89f1..c8ab8ea9e10d5 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -10,7 +10,6 @@ use prelude::v1::*; -use alloc::boxed::FnBox; use cmp; #[cfg(not(any(target_env = "newlib", target_os = "solaris")))] use ffi::CString; @@ -19,10 +18,9 @@ use libc; use mem; use ptr; use sys::os; +use sys::stack_overflow; use time::Duration; -use sys_common::thread::*; - pub struct Thread { id: libc::pthread_t, } @@ -33,9 +31,38 @@ unsafe impl Send for Thread {} unsafe impl Sync for Thread {} impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box) + pub unsafe fn new(stack: usize, p: F) -> io::Result { + + extern fn thread_start(main: *mut libc::c_void) + -> *mut libc::c_void { + unsafe { + let main = Box::from_raw(main as *mut F); + // Next, set up our stack overflow handler which may get triggered if we run + // out of stack. + let _handler = stack_overflow::Handler::new(); + + // Finally, let's run some code. + main(); + } + ptr::null_mut() + } + let p = box p; + + match Thread::new_inner(stack, &*p as *const _ as *const _, thread_start::) { + Ok(thread) => { + mem::forget(p); // ownership passed to pthread_create + Ok(thread) + } + + Err(e) => Err(e), + } + } + + unsafe fn new_inner(stack: usize, p: *const libc::c_void, + f: extern fn(*mut libc::c_void) -> *mut libc::c_void) + -> io::Result { let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); assert_eq!(libc::pthread_attr_init(&mut attr), 0); @@ -59,20 +86,14 @@ impl Thread { } }; - let ret = libc::pthread_create(&mut native, &attr, thread_start, - &*p as *const _ as *mut _); + let ret = libc::pthread_create(&mut native, &attr, f, + p as *mut _); assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); - return if ret != 0 { + if ret != 0 { Err(io::Error::from_raw_os_error(ret)) } else { - mem::forget(p); // ownership passed to pthread_create Ok(Thread { id: native }) - }; - - extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { - unsafe { start_thread(main); } - ptr::null_mut() } } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index b18772c0c2438..83f4f89685d67 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -17,7 +17,7 @@ use libc::c_void; use ptr; use sys::c; use sys::handle::Handle; -use sys_common::thread::*; +use sys::stack_overflow; use time::Duration; pub struct Thread { @@ -25,10 +25,37 @@ pub struct Thread { } impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box) + pub unsafe fn new(stack: usize, p: F) -> io::Result { + extern "system" fn thread_start(main: *mut c_void) + -> c::DWORD { + unsafe { + let main = Box::from_raw(main as *mut F); + + // Next, set up our stack overflow handler which may get triggered if we run + // out of stack. + let _handler = stack_overflow::Handler::new(); + + // Finally, let's run some code. + main(); + } + 0 + } + let p = box p; + match Thread::new_inner(stack, &*p as *const _ as *const _, thread_start::) { + Ok(thread) => { + mem::forget(p); // ownership passed to CreateThread + Ok(thread) + } + Err(e) => Err(e), + } + } + + unsafe fn new_inner(stack: usize, p: *const c_void, + f: extern "system" fn(*mut c_void) -> *mut c::DWORD) + -> io::Result { // FIXME On UNIX, we guard against stack sizes that are too small but // that's because pthreads enforces that stacks are at least // PTHREAD_STACK_MIN bytes big. Windows has no such lower limit, it's @@ -37,21 +64,15 @@ impl Thread { // Round up to the next 64 kB because that's what the NT kernel does, // might as well make it explicit. let stack_size = (stack + 0xfffe) & (!0xfffe); - let ret = c::CreateThread(ptr::null_mut(), stack_size, - thread_start, &*p as *const _ as *mut _, + let ret = c::CreateThread(ptr::null_mut(), stack, + f, p as *mut _, 0, ptr::null_mut()); return if ret as usize == 0 { Err(io::Error::last_os_error()) } else { - mem::forget(p); // ownership passed to CreateThread Ok(Thread { handle: Handle::new(ret) }) }; - - extern "system" fn thread_start(main: *mut c_void) -> c::DWORD { - unsafe { start_thread(main); } - 0 - } } pub fn set_name(_name: &str) { diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 116cd5da2ce7b..41b65c13c869f 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -284,7 +284,7 @@ impl Builder { Ok(JoinHandle(JoinInner { native: unsafe { - Some(try!(imp::Thread::new(stack_size, Box::new(main)))) + Some(try!(imp::Thread::new(stack_size, main))) }, thread: my_thread, packet: Packet(my_packet),