//! Threads are represented via the [`Thread`] type, which you can get in one of
//! two ways:
//!
-//! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
+//! * By spawning a new thread, e.g., using the [`thread::spawn`][`spawn`]
//! function, and calling [`thread`][`JoinHandle::thread`] on the [`JoinHandle`].
//! * By requesting the current thread, using the [`thread::current`] function.
//!
//! thread, use [`Thread::name`]. A couple examples of where the name of a thread gets used:
//!
//! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
-//! * The thread name is provided to the OS where applicable (e.g. `pthread_setname_np` in
+//! * The thread name is provided to the OS where applicable (e.g., `pthread_setname_np` in
//! unix-like platforms).
//!
//! ## Stack size
#![stable(feature = "rust1", since = "1.0.0")]
use any::Any;
+use boxed::FnBox;
use cell::UnsafeCell;
use ffi::{CStr, CString};
use fmt;
use io;
+use mem;
use panic;
use panicking;
use str;
/// Sets the size of the stack (in bytes) for the new thread.
///
/// The actual stack size may be greater than this value if
- /// the platform specifies minimal stack size.
+ /// the platform specifies a minimal stack size.
///
/// For more information about the stack size for threads, see
/// [this module-level documentation][stack-size].
///
/// - ensure that [`join`][`JoinHandle::join`] is called before any referenced
/// data is dropped
- /// - use only types with `'static` lifetime bounds, i.e. those with no or only
+ /// - use only types with `'static` lifetime bounds, i.e., those with no or only
/// `'static` references (both [`thread::Builder::spawn`][`Builder::spawn`]
/// and [`thread::spawn`][`spawn`] enforce this property statically)
///
/// [`io::Result`]: ../../std/io/type.Result.html
/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
#[unstable(feature = "thread_spawn_unchecked", issue = "55132")]
- pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
- F: FnOnce() -> T, F: Send, T: Send
+ pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
+ F: FnOnce() -> T, F: Send + 'a, T: Send + 'a
{
let Builder { name, stack_size } = self;
};
Ok(JoinHandle(JoinInner {
- native: Some(imp::Thread::new(stack_size, Box::new(main))?),
+ // `imp::Thread::new` takes a closure with a `'static` lifetime, since it's passed
+ // through FFI or otherwise used with low-level threading primitives that have no
+ // notion of or way to enforce lifetimes.
+ //
+ // As mentioned in the `Safety` section of this function's documentation, the caller of
+ // this function needs to guarantee that the passed-in lifetime is sufficiently long
+ // for the lifetime of the thread.
+ //
+ // Similarly, the `sys` implementation must guarantee that no references to the closure
+ // exist after the thread has terminated, which is signaled by `Thread::join`
+ // returning.
+ native: Some(imp::Thread::new(
+ stack_size,
+ mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(main))
+ )?),
thread: my_thread,
packet: Packet(my_packet),
}))
/// already poison themselves when a thread panics while holding the lock.
///
/// This can also be used in multithreaded applications, in order to send a
-/// message to other threads warning that a thread has panicked (e.g. for
+/// message to other threads warning that a thread has panicked (e.g., for
/// monitoring purposes).
///
/// # Examples
/// Threads are represented via the `Thread` type, which you can get in one of
/// two ways:
///
-/// * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
+/// * By spawning a new thread, e.g., using the [`thread::spawn`][`spawn`]
/// function, and calling [`thread`][`JoinHandle::thread`] on the
/// [`JoinHandle`].
/// * By requesting the current thread, using the [`thread::current`] function.