]> git.proxmox.com Git - rustc.git/blame - src/libstd/thread/mod.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / libstd / thread / mod.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
54a0048b 11//! Native threads.
1a4d82fc
JJ
12//!
13//! ## The threading model
14//!
15//! An executing Rust program consists of a collection of native OS threads,
a7813a04
XL
16//! each with their own stack and local state. Threads can be named, and
17//! provide some built-in support for low-level synchronization.
1a4d82fc
JJ
18//!
19//! Communication between threads can be done through
476ff2be 20//! [channels], Rust's message-passing types, along with [other forms of thread
1a4d82fc
JJ
21//! synchronization](../../std/sync/index.html) and shared-memory data
22//! structures. In particular, types that are guaranteed to be
23//! threadsafe are easily shared between threads using the
476ff2be 24//! atomically-reference-counted container, [`Arc`].
1a4d82fc
JJ
25//!
26//! Fatal logic errors in Rust cause *thread panic*, during which
27//! a thread will unwind the stack, running destructors and freeing
abe05a73
XL
28//! owned resources. While not meant as a 'try/catch' mechanism, panics
29//! in Rust can nonetheless be caught (unless compiling with `panic=abort`) with
30//! [`catch_unwind`](../../std/panic/fn.catch_unwind.html) and recovered
31//! from, or alternatively be resumed with
32//! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic
33//! is not caught the thread will exit, but the panic may optionally be
34//! detected from a different thread with [`join`]. If the main thread panics
35//! without the panic being caught, the application will exit with a
36//! non-zero exit code.
1a4d82fc
JJ
37//!
38//! When the main thread of a Rust program terminates, the entire program shuts
39//! down, even if other threads are still running. However, this module provides
40//! convenient facilities for automatically waiting for the termination of a
c34b1796 41//! child thread (i.e., join).
1a4d82fc 42//!
1a4d82fc
JJ
43//! ## Spawning a thread
44//!
476ff2be 45//! A new thread can be spawned using the [`thread::spawn`][`spawn`] function:
1a4d82fc
JJ
46//!
47//! ```rust
85aaf69f 48//! use std::thread;
1a4d82fc 49//!
85aaf69f 50//! thread::spawn(move || {
c34b1796 51//! // some work here
1a4d82fc
JJ
52//! });
53//! ```
54//!
85aaf69f 55//! In this example, the spawned thread is "detached" from the current
c34b1796
AL
56//! thread. This means that it can outlive its parent (the thread that spawned
57//! it), unless this parent is the main thread.
1a4d82fc 58//!
9346a6ac 59//! The parent thread can also wait on the completion of the child
476ff2be 60//! thread; a call to [`spawn`] produces a [`JoinHandle`], which provides
9346a6ac
AL
61//! a `join` method for waiting:
62//!
63//! ```rust
64//! use std::thread;
65//!
66//! let child = thread::spawn(move || {
67//! // some work here
68//! });
69//! // some work here
70//! let res = child.join();
71//! ```
72//!
7cac9316 73//! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
476ff2be
SL
74//! value produced by the child thread, or [`Err`] of the value given to
75//! a call to [`panic!`] if the child panicked.
9346a6ac 76//!
1a4d82fc
JJ
77//! ## Configuring threads
78//!
476ff2be 79//! A new thread can be configured before it is spawned via the [`Builder`] type,
bd371182 80//! which currently allows you to set the name and stack size for the child thread:
1a4d82fc
JJ
81//!
82//! ```rust
9346a6ac 83//! # #![allow(unused_must_use)]
1a4d82fc
JJ
84//! use std::thread;
85//!
86//! thread::Builder::new().name("child1".to_string()).spawn(move || {
c34b1796 87//! println!("Hello, world!");
1a4d82fc
JJ
88//! });
89//! ```
90//!
a7813a04
XL
91//! ## The `Thread` type
92//!
476ff2be 93//! Threads are represented via the [`Thread`] type, which you can get in one of
a7813a04
XL
94//! two ways:
95//!
476ff2be 96//! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
cc61c64b
XL
97//! function, and calling [`thread`][`JoinHandle::thread`] on the [`JoinHandle`].
98//! * By requesting the current thread, using the [`thread::current`] function.
a7813a04 99//!
cc61c64b 100//! The [`thread::current`] function is available even for threads not spawned
a7813a04
XL
101//! by the APIs of this module.
102//!
c34b1796
AL
103//! ## Thread-local storage
104//!
9e0c209e
SL
105//! This module also provides an implementation of thread-local storage for Rust
106//! programs. Thread-local storage is a method of storing data into a global
107//! variable that each thread in the program will have its own copy of.
c34b1796
AL
108//! Threads do not share this data, so accesses do not need to be synchronized.
109//!
9e0c209e
SL
110//! A thread-local key owns the value it contains and will destroy the value when the
111//! thread exits. It is created with the [`thread_local!`] macro and can contain any
112//! value that is `'static` (no borrowed pointers). It provides an accessor function,
113//! [`with`], that yields a shared reference to the value to the specified
114//! closure. Thread-local keys allow only shared access to values, as there would be no
115//! way to guarantee uniqueness if mutable borrows were allowed. Most values
c34b1796 116//! will want to make use of some form of **interior mutability** through the
9e0c209e
SL
117//! [`Cell`] or [`RefCell`] types.
118//!
3b2f2976
XL
119//! ## Naming threads
120//!
121//! Threads are able to have associated names for identification purposes. By default, spawned
122//! threads are unnamed. To specify a name for a thread, build the thread with [`Builder`] and pass
123//! the desired thread name to [`Builder::name`]. To retrieve the thread name from within the
124//! thread, use [`Thread::name`]. A couple examples of where the name of a thread gets used:
125//!
126//! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
127//! * The thread name is provided to the OS where applicable (e.g. `pthread_setname_np` in
128//! unix-like platforms).
129//!
130//! ## Stack size
131//!
132//! The default stack size for spawned threads is 2 MiB, though this particular stack size is
133//! subject to change in the future. There are two ways to manually specify the stack size for
134//! spawned threads:
135//!
136//! * Build the thread with [`Builder`] and pass the desired stack size to [`Builder::stack_size`].
137//! * Set the `RUST_MIN_STACK` environment variable to an integer representing the desired stack
138//! size (in bytes). Note that setting [`Builder::stack_size`] will override this.
139//!
140//! Note that the stack size of the main thread is *not* determined by Rust.
141//!
476ff2be
SL
142//! [channels]: ../../std/sync/mpsc/index.html
143//! [`Arc`]: ../../std/sync/struct.Arc.html
144//! [`spawn`]: ../../std/thread/fn.spawn.html
145//! [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
cc61c64b 146//! [`JoinHandle::thread`]: ../../std/thread/struct.JoinHandle.html#method.thread
476ff2be
SL
147//! [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
148//! [`Result`]: ../../std/result/enum.Result.html
149//! [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
150//! [`Err`]: ../../std/result/enum.Result.html#variant.Err
151//! [`panic!`]: ../../std/macro.panic.html
152//! [`Builder`]: ../../std/thread/struct.Builder.html
3b2f2976
XL
153//! [`Builder::stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size
154//! [`Builder::name`]: ../../std/thread/struct.Builder.html#method.name
cc61c64b 155//! [`thread::current`]: ../../std/thread/fn.current.html
7cac9316 156//! [`thread::Result`]: ../../std/thread/type.Result.html
476ff2be 157//! [`Thread`]: ../../std/thread/struct.Thread.html
cc61c64b
XL
158//! [`park`]: ../../std/thread/fn.park.html
159//! [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
3b2f2976 160//! [`Thread::name`]: ../../std/thread/struct.Thread.html#method.name
cc61c64b 161//! [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
9e0c209e
SL
162//! [`Cell`]: ../cell/struct.Cell.html
163//! [`RefCell`]: ../cell/struct.RefCell.html
c30ab7b3 164//! [`thread_local!`]: ../macro.thread_local.html
9e0c209e 165//! [`with`]: struct.LocalKey.html#method.with
1a4d82fc 166
85aaf69f
SL
167#![stable(feature = "rust1", since = "1.0.0")]
168
1a4d82fc 169use any::Any;
1a4d82fc 170use cell::UnsafeCell;
a7813a04 171use ffi::{CStr, CString};
85aaf69f
SL
172use fmt;
173use io;
a7813a04
XL
174use panic;
175use panicking;
54a0048b 176use str;
85aaf69f 177use sync::{Mutex, Condvar, Arc};
abe05a73
XL
178use sync::atomic::AtomicUsize;
179use sync::atomic::Ordering::SeqCst;
c34b1796 180use sys::thread as imp;
c30ab7b3 181use sys_common::mutex;
e9174d1e 182use sys_common::thread_info;
ea8adc8c 183use sys_common::thread;
92a42be0 184use sys_common::{AsInner, IntoInner};
85aaf69f 185use time::Duration;
1a4d82fc 186
c34b1796
AL
187////////////////////////////////////////////////////////////////////////////////
188// Thread-local storage
189////////////////////////////////////////////////////////////////////////////////
190
9346a6ac 191#[macro_use] mod local;
9346a6ac
AL
192
193#[stable(feature = "rust1", since = "1.0.0")]
041b39d2 194pub use self::local::{LocalKey, LocalKeyState, AccessError};
9346a6ac 195
c30ab7b3
SL
196// The types used by the thread_local! macro to access TLS keys. Note that there
197// are two types, the "OS" type and the "fast" type. The OS thread local key
198// type is accessed via platform-specific API calls and is slow, while the fast
199// key type is accessed via code generated via LLVM, where TLS keys are set up
200// by the elf linker. Note that the OS TLS type is always available: on macOS
201// the standard library is compiled with support for older platform versions
202// where fast TLS was not available; end-user code is compiled with fast TLS
203// where available, but both are needed.
204
92a42be0 205#[unstable(feature = "libstd_thread_internals", issue = "0")]
9cc50fc6 206#[cfg(target_thread_local)]
041b39d2 207#[doc(hidden)] pub use self::local::fast::Key as __FastLocalKeyInner;
9cc50fc6
SL
208#[unstable(feature = "libstd_thread_internals", issue = "0")]
209#[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner;
c34b1796
AL
210
211////////////////////////////////////////////////////////////////////////////////
212// Builder
213////////////////////////////////////////////////////////////////////////////////
1a4d82fc 214
7cac9316
XL
215/// Thread factory, which can be used in order to configure the properties of
216/// a new thread.
217///
218/// Methods can be chained on it in order to configure it.
219///
220/// The two configurations available are:
221///
3b2f2976
XL
222/// - [`name`]: specifies an [associated name for the thread][naming-threads]
223/// - [`stack_size`]: specifies the [desired stack size for the thread][stack-size]
7cac9316
XL
224///
225/// The [`spawn`] method will take ownership of the builder and create an
226/// [`io::Result`] to the thread handle with the given configuration.
227///
228/// The [`thread::spawn`] free function uses a `Builder` with default
229/// configuration and [`unwrap`]s its return value.
230///
231/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want
232/// to recover from a failure to launch a thread, indeed the free function will
233/// panick where the `Builder` method will return a [`io::Result`].
32a655c1
SL
234///
235/// # Examples
236///
237/// ```
238/// use std::thread;
239///
240/// let builder = thread::Builder::new();
241///
242/// let handler = builder.spawn(|| {
243/// // thread code
244/// }).unwrap();
245///
246/// handler.join().unwrap();
247/// ```
7cac9316
XL
248///
249/// [`thread::spawn`]: ../../std/thread/fn.spawn.html
250/// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size
251/// [`name`]: ../../std/thread/struct.Builder.html#method.name
252/// [`spawn`]: ../../std/thread/struct.Builder.html#method.spawn
253/// [`io::Result`]: ../../std/io/type.Result.html
254/// [`unwrap`]: ../../std/result/enum.Result.html#method.unwrap
3b2f2976
XL
255/// [naming-threads]: ./index.html#naming-threads
256/// [stack-size]: ./index.html#stack-size
85aaf69f 257#[stable(feature = "rust1", since = "1.0.0")]
32a655c1 258#[derive(Debug)]
1a4d82fc
JJ
259pub struct Builder {
260 // A name for the thread-to-be, for identification in panic messages
261 name: Option<String>,
8bb4bdeb 262 // The size of the stack for the spawned thread in bytes
c34b1796 263 stack_size: Option<usize>,
1a4d82fc
JJ
264}
265
266impl Builder {
9346a6ac 267 /// Generates the base configuration for spawning a thread, from which
1a4d82fc 268 /// configuration methods can be chained.
32a655c1
SL
269 ///
270 /// # Examples
271 ///
272 /// ```
273 /// use std::thread;
274 ///
275 /// let builder = thread::Builder::new()
276 /// .name("foo".into())
277 /// .stack_size(10);
278 ///
279 /// let handler = builder.spawn(|| {
280 /// // thread code
281 /// }).unwrap();
282 ///
283 /// handler.join().unwrap();
284 /// ```
85aaf69f 285 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
286 pub fn new() -> Builder {
287 Builder {
288 name: None,
289 stack_size: None,
1a4d82fc
JJ
290 }
291 }
292
9346a6ac 293 /// Names the thread-to-be. Currently the name is used for identification
1a4d82fc 294 /// only in panic messages.
3157f602 295 ///
ea8adc8c
XL
296 /// The name must not contain null bytes (`\0`).
297 ///
3b2f2976
XL
298 /// For more information about named threads, see
299 /// [this module-level documentation][naming-threads].
300 ///
3157f602
XL
301 /// # Examples
302 ///
32a655c1 303 /// ```
3157f602
XL
304 /// use std::thread;
305 ///
306 /// let builder = thread::Builder::new()
307 /// .name("foo".into());
308 ///
309 /// let handler = builder.spawn(|| {
310 /// assert_eq!(thread::current().name(), Some("foo"))
311 /// }).unwrap();
312 ///
313 /// handler.join().unwrap();
314 /// ```
3b2f2976
XL
315 ///
316 /// [naming-threads]: ./index.html#naming-threads
85aaf69f 317 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
318 pub fn name(mut self, name: String) -> Builder {
319 self.name = Some(name);
320 self
321 }
322
8bb4bdeb
XL
323 /// Sets the size of the stack (in bytes) for the new thread.
324 ///
325 /// The actual stack size may be greater than this value if
326 /// the platform specifies minimal stack size.
32a655c1 327 ///
3b2f2976
XL
328 /// For more information about the stack size for threads, see
329 /// [this module-level documentation][stack-size].
330 ///
32a655c1
SL
331 /// # Examples
332 ///
333 /// ```
334 /// use std::thread;
335 ///
8bb4bdeb 336 /// let builder = thread::Builder::new().stack_size(32 * 1024);
32a655c1 337 /// ```
3b2f2976
XL
338 ///
339 /// [stack-size]: ./index.html#stack-size
85aaf69f 340 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796 341 pub fn stack_size(mut self, size: usize) -> Builder {
1a4d82fc
JJ
342 self.stack_size = Some(size);
343 self
344 }
345
7cac9316
XL
346 /// Spawns a new thread by taking ownership of the `Builder`, and returns an
347 /// [`io::Result`] to its [`JoinHandle`].
1a4d82fc 348 ///
7cac9316 349 /// The spawned thread may outlive the caller (unless the caller thread
85aaf69f 350 /// is the main thread; the whole process is terminated when the main
bd371182 351 /// thread finishes). The join handle can be used to block on
85aaf69f
SL
352 /// termination of the child thread, including recovering its panics.
353 ///
7cac9316
XL
354 /// For a more complete documentation see [`thread::spawn`][`spawn`].
355 ///
85aaf69f
SL
356 /// # Errors
357 ///
32a655c1
SL
358 /// Unlike the [`spawn`] free function, this method yields an
359 /// [`io::Result`] to capture any failure to create the thread at
85aaf69f 360 /// the OS level.
32a655c1
SL
361 ///
362 /// [`spawn`]: ../../std/thread/fn.spawn.html
363 /// [`io::Result`]: ../../std/io/type.Result.html
7cac9316 364 /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
32a655c1 365 ///
ea8adc8c
XL
366 /// # Panics
367 ///
368 /// Panics if a thread name was set and it contained null bytes.
369 ///
32a655c1
SL
370 /// # Examples
371 ///
372 /// ```
373 /// use std::thread;
374 ///
375 /// let builder = thread::Builder::new();
376 ///
377 /// let handler = builder.spawn(|| {
378 /// // thread code
379 /// }).unwrap();
380 ///
381 /// handler.join().unwrap();
382 /// ```
85aaf69f 383 #[stable(feature = "rust1", since = "1.0.0")]
9346a6ac
AL
384 pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
385 F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
85aaf69f 386 {
c34b1796 387 let Builder { name, stack_size } = self;
1a4d82fc 388
ea8adc8c 389 let stack_size = stack_size.unwrap_or_else(thread::min_stack);
85aaf69f 390
1a4d82fc
JJ
391 let my_thread = Thread::new(name);
392 let their_thread = my_thread.clone();
393
b039eaaf
SL
394 let my_packet : Arc<UnsafeCell<Option<Result<T>>>>
395 = Arc::new(UnsafeCell::new(None));
d9579d0f 396 let their_packet = my_packet.clone();
85aaf69f 397
85aaf69f 398 let main = move || {
54a0048b 399 if let Some(name) = their_thread.cname() {
d9579d0f 400 imp::Thread::set_name(name);
85aaf69f 401 }
b039eaaf
SL
402 unsafe {
403 thread_info::set(imp::guard::current(), their_thread);
7cac9316
XL
404 #[cfg(feature = "backtrace")]
405 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
406 ::sys_common::backtrace::__rust_begin_short_backtrace(f)
407 }));
408 #[cfg(not(feature = "backtrace"))]
a7813a04
XL
409 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
410 *their_packet.get() = Some(try_result);
b039eaaf 411 }
1a4d82fc
JJ
412 };
413
b039eaaf
SL
414 Ok(JoinHandle(JoinInner {
415 native: unsafe {
54a0048b 416 Some(imp::Thread::new(stack_size, Box::new(main))?)
b039eaaf 417 },
85aaf69f 418 thread: my_thread,
d9579d0f 419 packet: Packet(my_packet),
b039eaaf 420 }))
1a4d82fc
JJ
421 }
422}
423
c34b1796
AL
424////////////////////////////////////////////////////////////////////////////////
425// Free functions
426////////////////////////////////////////////////////////////////////////////////
427
32a655c1 428/// Spawns a new thread, returning a [`JoinHandle`] for it.
85aaf69f 429///
c34b1796
AL
430/// The join handle will implicitly *detach* the child thread upon being
431/// dropped. In this case, the child thread may outlive the parent (unless
432/// the parent thread is the main thread; the whole process is terminated when
32a655c1 433/// the main thread finishes). Additionally, the join handle provides a [`join`]
c34b1796 434/// method that can be used to join the child thread. If the child thread
32a655c1
SL
435/// panics, [`join`] will return an [`Err`] containing the argument given to
436/// [`panic`].
85aaf69f 437///
7cac9316
XL
438/// This will create a thread using default parameters of [`Builder`], if you
439/// want to specify the stack size or the name of the thread, use this API
440/// instead.
441///
442/// As you can see in the signature of `spawn` there are two constraints on
443/// both the closure given to `spawn` and its return value, let's explain them:
444///
445/// - The `'static` constraint means that the closure and its return value
446/// must have a lifetime of the whole program execution. The reason for this
447/// is that threads can `detach` and outlive the lifetime they have been
448/// created in.
449/// Indeed if the thread, and by extension its return value, can outlive their
450/// caller, we need to make sure that they will be valid afterwards, and since
451/// we *can't* know when it will return we need to have them valid as long as
452/// possible, that is until the end of the program, hence the `'static`
453/// lifetime.
454/// - The [`Send`] constraint is because the closure will need to be passed
455/// *by value* from the thread where it is spawned to the new thread. Its
456/// return value will need to be passed from the new thread to the thread
457/// where it is `join`ed.
3b2f2976 458/// As a reminder, the [`Send`] marker trait expresses that it is safe to be
7cac9316
XL
459/// passed from thread to thread. [`Sync`] expresses that it is safe to have a
460/// reference be passed from thread to thread.
461///
85aaf69f
SL
462/// # Panics
463///
32a655c1 464/// Panics if the OS fails to create a thread; use [`Builder::spawn`]
85aaf69f 465/// to recover from such errors.
32a655c1 466///
32a655c1
SL
467/// # Examples
468///
7cac9316
XL
469/// Creating a thread.
470///
32a655c1
SL
471/// ```
472/// use std::thread;
473///
474/// let handler = thread::spawn(|| {
475/// // thread code
476/// });
477///
478/// handler.join().unwrap();
479/// ```
7cac9316
XL
480///
481/// As mentioned in the module documentation, threads are usually made to
482/// communicate using [`channels`], here is how it usually looks.
483///
484/// This example also shows how to use `move`, in order to give ownership
485/// of values to a thread.
486///
487/// ```
488/// use std::thread;
489/// use std::sync::mpsc::channel;
490///
491/// let (tx, rx) = channel();
492///
493/// let sender = thread::spawn(move || {
abe05a73
XL
494/// tx.send("Hello, thread".to_owned())
495/// .expect("Unable to send on channel");
7cac9316
XL
496/// });
497///
498/// let receiver = thread::spawn(move || {
abe05a73
XL
499/// let value = rx.recv().expect("Unable to receive from channel");
500/// println!("{}", value);
7cac9316
XL
501/// });
502///
abe05a73
XL
503/// sender.join().expect("The sender thread has panicked");
504/// receiver.join().expect("The receiver thread has panicked");
7cac9316
XL
505/// ```
506///
507/// A thread can also return a value through its [`JoinHandle`], you can use
508/// this to make asynchronous computations (futures might be more appropriate
509/// though).
510///
511/// ```
512/// use std::thread;
513///
514/// let computation = thread::spawn(|| {
515/// // Some expensive computation.
516/// 42
517/// });
518///
519/// let result = computation.join().unwrap();
520/// println!("{}", result);
521/// ```
522///
523/// [`channels`]: ../../std/sync/mpsc/index.html
524/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
525/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
526/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
527/// [`panic`]: ../../std/macro.panic.html
528/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
529/// [`Builder`]: ../../std/thread/struct.Builder.html
530/// [`Send`]: ../../std/marker/trait.Send.html
531/// [`Sync`]: ../../std/marker/trait.Sync.html
85aaf69f 532#[stable(feature = "rust1", since = "1.0.0")]
9346a6ac
AL
533pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
534 F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
535{
85aaf69f
SL
536 Builder::new().spawn(f).unwrap()
537}
538
85aaf69f 539/// Gets a handle to the thread that invokes it.
9e0c209e 540///
32a655c1 541/// # Examples
9e0c209e
SL
542///
543/// Getting a handle to the current thread with `thread::current()`:
544///
545/// ```
546/// use std::thread;
547///
548/// let handler = thread::Builder::new()
549/// .name("named thread".into())
550/// .spawn(|| {
551/// let handle = thread::current();
552/// assert_eq!(handle.name(), Some("named thread"));
553/// })
554/// .unwrap();
555///
556/// handler.join().unwrap();
557/// ```
85aaf69f
SL
558#[stable(feature = "rust1", since = "1.0.0")]
559pub fn current() -> Thread {
d9579d0f
AL
560 thread_info::current_thread().expect("use of std::thread::current() is not \
561 possible after the thread's local \
562 data has been destroyed")
85aaf69f
SL
563}
564
9346a6ac 565/// Cooperatively gives up a timeslice to the OS scheduler.
32a655c1 566///
7cac9316
XL
567/// This is used when the programmer knows that the thread will have nothing
568/// to do for some time, and thus avoid wasting computing time.
569///
570/// For example when polling on a resource, it is common to check that it is
571/// available, and if not to yield in order to avoid busy waiting.
572///
573/// Thus the pattern of `yield`ing after a failed poll is rather common when
574/// implementing low-level shared resources or synchronization primitives.
575///
3b2f2976
XL
576/// However programmers will usually prefer to use, [`channel`]s, [`Condvar`]s,
577/// [`Mutex`]es or [`join`] for their synchronization routines, as they avoid
578/// thinking about thread scheduling.
7cac9316
XL
579///
580/// Note that [`channel`]s for example are implemented using this primitive.
581/// Indeed when you call `send` or `recv`, which are blocking, they will yield
582/// if the channel is not available.
583///
32a655c1
SL
584/// # Examples
585///
586/// ```
587/// use std::thread;
588///
589/// thread::yield_now();
590/// ```
7cac9316
XL
591///
592/// [`channel`]: ../../std/sync/mpsc/index.html
593/// [`spawn`]: ../../std/thread/fn.spawn.html
594/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
595/// [`Mutex`]: ../../std/sync/struct.Mutex.html
596/// [`Condvar`]: ../../std/sync/struct.Condvar.html
85aaf69f
SL
597#[stable(feature = "rust1", since = "1.0.0")]
598pub fn yield_now() {
d9579d0f 599 imp::Thread::yield_now()
85aaf69f
SL
600}
601
602/// Determines whether the current thread is unwinding because of panic.
3157f602 603///
7cac9316
XL
604/// A common use of this feature is to poison shared resources when writing
605/// unsafe code, by checking `panicking` when the `drop` is called.
606///
607/// This is usually not needed when writing safe code, as [`Mutex`es][Mutex]
608/// already poison themselves when a thread panics while holding the lock.
609///
610/// This can also be used in multithreaded applications, in order to send a
611/// message to other threads warning that a thread has panicked (e.g. for
612/// monitoring purposes).
613///
3157f602
XL
614/// # Examples
615///
32a655c1 616/// ```should_panic
3157f602
XL
617/// use std::thread;
618///
619/// struct SomeStruct;
620///
621/// impl Drop for SomeStruct {
622/// fn drop(&mut self) {
623/// if thread::panicking() {
624/// println!("dropped while unwinding");
625/// } else {
626/// println!("dropped while not unwinding");
627/// }
628/// }
629/// }
630///
631/// {
632/// print!("a: ");
633/// let a = SomeStruct;
634/// }
635///
636/// {
637/// print!("b: ");
638/// let b = SomeStruct;
639/// panic!()
640/// }
641/// ```
7cac9316
XL
642///
643/// [Mutex]: ../../std/sync/struct.Mutex.html
85aaf69f
SL
644#[inline]
645#[stable(feature = "rust1", since = "1.0.0")]
646pub fn panicking() -> bool {
a7813a04 647 panicking::panicking()
85aaf69f
SL
648}
649
9346a6ac 650/// Puts the current thread to sleep for the specified amount of time.
c34b1796
AL
651///
652/// The thread may sleep longer than the duration specified due to scheduling
32a655c1
SL
653/// specifics or platform-dependent functionality.
654///
655/// # Platform behavior
656///
657/// On Unix platforms this function will not return early due to a
658/// signal being received or a spurious wakeup.
659///
660/// # Examples
661///
662/// ```no_run
663/// use std::thread;
664///
665/// // Let's sleep for 2 seconds:
666/// thread::sleep_ms(2000);
667/// ```
c34b1796 668#[stable(feature = "rust1", since = "1.0.0")]
92a42be0 669#[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::sleep`")]
c34b1796 670pub fn sleep_ms(ms: u32) {
d9579d0f
AL
671 sleep(Duration::from_millis(ms as u64))
672}
673
674/// Puts the current thread to sleep for the specified amount of time.
675///
676/// The thread may sleep longer than the duration specified due to scheduling
677/// specifics or platform-dependent functionality.
678///
679/// # Platform behavior
680///
681/// On Unix platforms this function will not return early due to a
682/// signal being received or a spurious wakeup. Platforms which do not support
683/// nanosecond precision for sleeping will have `dur` rounded up to the nearest
684/// granularity of time they can sleep for.
3157f602
XL
685///
686/// # Examples
687///
32a655c1 688/// ```no_run
3157f602
XL
689/// use std::{thread, time};
690///
691/// let ten_millis = time::Duration::from_millis(10);
692/// let now = time::Instant::now();
693///
694/// thread::sleep(ten_millis);
695///
696/// assert!(now.elapsed() >= ten_millis);
697/// ```
e9174d1e 698#[stable(feature = "thread_sleep", since = "1.4.0")]
d9579d0f
AL
699pub fn sleep(dur: Duration) {
700 imp::Thread::sleep(dur)
c34b1796
AL
701}
702
abe05a73
XL
703// constants for park/unpark
704const EMPTY: usize = 0;
705const PARKED: usize = 1;
706const NOTIFIED: usize = 2;
707
c1a9b12d
SL
708/// Blocks unless or until the current thread's token is made available.
709///
7cac9316
XL
710/// A call to `park` does not guarantee that the thread will remain parked
711/// forever, and callers should be prepared for this possibility.
712///
713/// # park and unpark
714///
715/// Every thread is equipped with some basic low-level blocking support, via the
716/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`]
717/// method. [`park`] blocks the current thread, which can then be resumed from
718/// another thread by calling the [`unpark`] method on the blocked thread's
719/// handle.
720///
721/// Conceptually, each [`Thread`] handle has an associated token, which is
722/// initially not present:
c1a9b12d 723///
7cac9316
XL
724/// * The [`thread::park`][`park`] function blocks the current thread unless or
725/// until the token is available for its thread handle, at which point it
726/// atomically consumes the token. It may also return *spuriously*, without
727/// consuming the token. [`thread::park_timeout`] does the same, but allows
728/// specifying a maximum time to block the thread for.
729///
730/// * The [`unpark`] method on a [`Thread`] atomically makes the token available
731/// if it wasn't already.
732///
733/// In other words, each [`Thread`] acts a bit like a spinlock that can be
734/// locked and unlocked using `park` and `unpark`.
c1a9b12d
SL
735///
736/// The API is typically used by acquiring a handle to the current thread,
737/// placing that handle in a shared data structure so that other threads can
7cac9316
XL
738/// find it, and then `park`ing. When some desired condition is met, another
739/// thread calls [`unpark`] on the handle.
c1a9b12d 740///
7cac9316 741/// The motivation for this design is twofold:
c1a9b12d 742///
7cac9316
XL
743/// * It avoids the need to allocate mutexes and condvars when building new
744/// synchronization primitives; the threads already provide basic
745/// blocking/signaling.
85aaf69f 746///
7cac9316
XL
747/// * It can be implemented very efficiently on many platforms.
748///
749/// # Examples
750///
751/// ```
752/// use std::thread;
753/// use std::time::Duration;
754///
755/// let parked_thread = thread::Builder::new()
756/// .spawn(|| {
757/// println!("Parking thread");
758/// thread::park();
759/// println!("Thread unparked");
760/// })
761/// .unwrap();
762///
763/// // Let some time pass for the thread to be spawned.
764/// thread::sleep(Duration::from_millis(10));
765///
766/// println!("Unpark the thread");
767/// parked_thread.thread().unpark();
768///
769/// parked_thread.join().unwrap();
770/// ```
771///
772/// [`Thread`]: ../../std/thread/struct.Thread.html
773/// [`park`]: ../../std/thread/fn.park.html
774/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
775/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
85aaf69f
SL
776//
777// The implementation currently uses the trivial strategy of a Mutex+Condvar
778// with wakeup flag, which does not actually allow spurious wakeups. In the
779// future, this will be implemented in a more efficient way, perhaps along the lines of
780// http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
781// or futuxes, and in either case may allow spurious wakeups.
782#[stable(feature = "rust1", since = "1.0.0")]
783pub fn park() {
784 let thread = current();
abe05a73
XL
785
786 // If we were previously notified then we consume this notification and
787 // return quickly.
788 if thread.inner.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
789 return
790 }
791
792 // Otherwise we need to coordinate going to sleep
793 let mut m = thread.inner.lock.lock().unwrap();
794 match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
795 Ok(_) => {}
796 Err(NOTIFIED) => return, // notified after we locked
797 Err(_) => panic!("inconsistent park state"),
798 }
799 loop {
800 m = thread.inner.cvar.wait(m).unwrap();
801 match thread.inner.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) {
802 Ok(_) => return, // got a notification
803 Err(_) => {} // spurious wakeup, go back to sleep
804 }
85aaf69f 805 }
85aaf69f
SL
806}
807
7cac9316 808/// Use [`park_timeout`].
5bcae85e 809///
9346a6ac 810/// Blocks unless or until the current thread's token is made available or
85aaf69f
SL
811/// the specified duration has been reached (may wake spuriously).
812///
7cac9316
XL
813/// The semantics of this function are equivalent to [`park`] except
814/// that the thread will be blocked for roughly no longer than `dur`. This
815/// method should not be used for precise timing due to anomalies such as
85aaf69f 816/// preemption or platform differences that may not cause the maximum
3157f602 817/// amount of time waited to be precisely `ms` long.
85aaf69f 818///
7cac9316 819/// See the [park documentation][`park`] for more detail.
5bcae85e 820///
7cac9316
XL
821/// [`park_timeout`]: fn.park_timeout.html
822/// [`park`]: ../../std/thread/fn.park.html
c34b1796 823#[stable(feature = "rust1", since = "1.0.0")]
92a42be0 824#[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
c34b1796 825pub fn park_timeout_ms(ms: u32) {
d9579d0f
AL
826 park_timeout(Duration::from_millis(ms as u64))
827}
828
829/// Blocks unless or until the current thread's token is made available or
830/// the specified duration has been reached (may wake spuriously).
831///
7cac9316
XL
832/// The semantics of this function are equivalent to [`park`][park] except
833/// that the thread will be blocked for roughly no longer than `dur`. This
834/// method should not be used for precise timing due to anomalies such as
d9579d0f 835/// preemption or platform differences that may not cause the maximum
3157f602 836/// amount of time waited to be precisely `dur` long.
d9579d0f 837///
3b2f2976 838/// See the [park documentation][park] for more details.
d9579d0f
AL
839///
840/// # Platform behavior
841///
842/// Platforms which do not support nanosecond precision for sleeping will have
843/// `dur` rounded up to the nearest granularity of time they can sleep for.
5bcae85e 844///
3b2f2976 845/// # Examples
5bcae85e
SL
846///
847/// Waiting for the complete expiration of the timeout:
848///
849/// ```rust,no_run
850/// use std::thread::park_timeout;
851/// use std::time::{Instant, Duration};
852///
853/// let timeout = Duration::from_secs(2);
854/// let beginning_park = Instant::now();
5bcae85e 855///
041b39d2
XL
856/// let mut timeout_remaining = timeout;
857/// loop {
858/// park_timeout(timeout_remaining);
859/// let elapsed = beginning_park.elapsed();
860/// if elapsed >= timeout {
861/// break;
862/// }
863/// println!("restarting park_timeout after {:?}", elapsed);
864/// timeout_remaining = timeout - elapsed;
5bcae85e
SL
865/// }
866/// ```
7cac9316
XL
867///
868/// [park]: fn.park.html
e9174d1e 869#[stable(feature = "park_timeout", since = "1.4.0")]
d9579d0f 870pub fn park_timeout(dur: Duration) {
85aaf69f 871 let thread = current();
abe05a73
XL
872
873 // Like `park` above we have a fast path for an already-notified thread, and
874 // afterwards we start coordinating for a sleep.
875 // return quickly.
876 if thread.inner.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
877 return
878 }
879 let m = thread.inner.lock.lock().unwrap();
880 match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
881 Ok(_) => {}
882 Err(NOTIFIED) => return, // notified after we locked
883 Err(_) => panic!("inconsistent park_timeout state"),
884 }
885
886 // Wait with a timeout, and if we spuriously wake up or otherwise wake up
887 // from a notification we just want to unconditionally set the state back to
888 // empty, either consuming a notification or un-flagging ourselves as
889 // parked.
890 let (_m, _result) = thread.inner.cvar.wait_timeout(m, dur).unwrap();
891 match thread.inner.state.swap(EMPTY, SeqCst) {
892 NOTIFIED => {} // got a notification, hurray!
893 PARKED => {} // no notification, alas
894 n => panic!("inconsistent park_timeout state: {}", n),
85aaf69f 895 }
85aaf69f
SL
896}
897
c30ab7b3
SL
898////////////////////////////////////////////////////////////////////////////////
899// ThreadId
900////////////////////////////////////////////////////////////////////////////////
901
902/// A unique identifier for a running thread.
903///
904/// A `ThreadId` is an opaque object that has a unique value for each thread
cc61c64b 905/// that creates one. `ThreadId`s are not guaranteed to correspond to a thread's
3b2f2976
XL
906/// system-designated identifier. A `ThreadId` can be retrieved from the [`id`]
907/// method on a [`Thread`].
32a655c1
SL
908///
909/// # Examples
910///
911/// ```
32a655c1
SL
912/// use std::thread;
913///
cc61c64b
XL
914/// let other_thread = thread::spawn(|| {
915/// thread::current().id()
916/// });
32a655c1 917///
cc61c64b
XL
918/// let other_thread_id = other_thread.join().unwrap();
919/// assert!(thread::current().id() != other_thread_id);
32a655c1 920/// ```
3b2f2976
XL
921///
922/// [`id`]: ../../std/thread/struct.Thread.html#method.id
923/// [`Thread`]: ../../std/thread/struct.Thread.html
7cac9316 924#[stable(feature = "thread_id", since = "1.19.0")]
cc61c64b 925#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
c30ab7b3
SL
926pub struct ThreadId(u64);
927
928impl ThreadId {
929 // Generate a new unique thread ID.
930 fn new() -> ThreadId {
931 static GUARD: mutex::Mutex = mutex::Mutex::new();
932 static mut COUNTER: u64 = 0;
933
934 unsafe {
935 GUARD.lock();
936
937 // If we somehow use up all our bits, panic so that we're not
938 // covering up subtle bugs of IDs being reused.
939 if COUNTER == ::u64::MAX {
940 GUARD.unlock();
941 panic!("failed to generate unique thread ID: bitspace exhausted");
942 }
943
944 let id = COUNTER;
945 COUNTER += 1;
946
947 GUARD.unlock();
948
949 ThreadId(id)
950 }
951 }
952}
953
c34b1796
AL
954////////////////////////////////////////////////////////////////////////////////
955// Thread
956////////////////////////////////////////////////////////////////////////////////
957
85aaf69f 958/// The internal representation of a `Thread` handle
1a4d82fc 959struct Inner {
54a0048b 960 name: Option<CString>, // Guaranteed to be UTF-8
c30ab7b3 961 id: ThreadId,
abe05a73
XL
962
963 // state for thread park/unpark
964 state: AtomicUsize,
965 lock: Mutex<()>,
1a4d82fc
JJ
966 cvar: Condvar,
967}
968
1a4d82fc 969#[derive(Clone)]
85aaf69f 970#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 971/// A handle to a thread.
32a655c1 972///
7cac9316
XL
973/// Threads are represented via the `Thread` type, which you can get in one of
974/// two ways:
32a655c1 975///
7cac9316
XL
976/// * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
977/// function, and calling [`thread`][`JoinHandle::thread`] on the
978/// [`JoinHandle`].
979/// * By requesting the current thread, using the [`thread::current`] function.
32a655c1 980///
7cac9316
XL
981/// The [`thread::current`] function is available even for threads not spawned
982/// by the APIs of this module.
32a655c1 983///
3b2f2976 984/// There is usually no need to create a `Thread` struct yourself, one
7cac9316
XL
985/// should instead use a function like `spawn` to create new threads, see the
986/// docs of [`Builder`] and [`spawn`] for more details.
987///
988/// [`Builder`]: ../../std/thread/struct.Builder.html
3b2f2976
XL
989/// [`JoinHandle::thread`]: ../../std/thread/struct.JoinHandle.html#method.thread
990/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
991/// [`thread::current`]: ../../std/thread/fn.current.html
7cac9316
XL
992/// [`spawn`]: ../../std/thread/fn.spawn.html
993
1a4d82fc
JJ
994pub struct Thread {
995 inner: Arc<Inner>,
996}
997
998impl Thread {
999 // Used only internally to construct a thread object without spawning
ea8adc8c 1000 // Panics if the name contains nuls.
cc61c64b 1001 pub(crate) fn new(name: Option<String>) -> Thread {
3157f602
XL
1002 let cname = name.map(|n| {
1003 CString::new(n).expect("thread name may not contain interior null bytes")
1004 });
1a4d82fc
JJ
1005 Thread {
1006 inner: Arc::new(Inner {
54a0048b 1007 name: cname,
c30ab7b3 1008 id: ThreadId::new(),
abe05a73
XL
1009 state: AtomicUsize::new(EMPTY),
1010 lock: Mutex::new(()),
1a4d82fc
JJ
1011 cvar: Condvar::new(),
1012 })
1013 }
1014 }
1015
1a4d82fc
JJ
1016 /// Atomically makes the handle's token available if it is not already.
1017 ///
7cac9316
XL
1018 /// Every thread is equipped with some basic low-level blocking support, via
1019 /// the [`park`][park] function and the `unpark()` method. These can be
1020 /// used as a more CPU-efficient implementation of a spinlock.
1021 ///
1022 /// See the [park documentation][park] for more details.
32a655c1
SL
1023 ///
1024 /// # Examples
1025 ///
1026 /// ```
1027 /// use std::thread;
7cac9316 1028 /// use std::time::Duration;
32a655c1 1029 ///
7cac9316 1030 /// let parked_thread = thread::Builder::new()
32a655c1 1031 /// .spawn(|| {
7cac9316
XL
1032 /// println!("Parking thread");
1033 /// thread::park();
1034 /// println!("Thread unparked");
32a655c1
SL
1035 /// })
1036 /// .unwrap();
1037 ///
7cac9316
XL
1038 /// // Let some time pass for the thread to be spawned.
1039 /// thread::sleep(Duration::from_millis(10));
1040 ///
1041 /// println!("Unpark the thread");
1042 /// parked_thread.thread().unpark();
1043 ///
1044 /// parked_thread.join().unwrap();
32a655c1 1045 /// ```
7cac9316
XL
1046 ///
1047 /// [park]: fn.park.html
85aaf69f 1048 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1049 pub fn unpark(&self) {
abe05a73
XL
1050 loop {
1051 match self.inner.state.compare_exchange(EMPTY, NOTIFIED, SeqCst, SeqCst) {
1052 Ok(_) => return, // no one was waiting
1053 Err(NOTIFIED) => return, // already unparked
1054 Err(PARKED) => {} // gotta go wake someone up
1055 _ => panic!("inconsistent state in unpark"),
1056 }
1057
1058 // Coordinate wakeup through the mutex and a condvar notification
1059 let _lock = self.inner.lock.lock().unwrap();
1060 match self.inner.state.compare_exchange(PARKED, NOTIFIED, SeqCst, SeqCst) {
1061 Ok(_) => return self.inner.cvar.notify_one(),
1062 Err(NOTIFIED) => return, // a different thread unparked
1063 Err(EMPTY) => {} // parked thread went away, try again
1064 _ => panic!("inconsistent state in unpark"),
1065 }
1a4d82fc
JJ
1066 }
1067 }
1068
c30ab7b3 1069 /// Gets the thread's unique identifier.
32a655c1
SL
1070 ///
1071 /// # Examples
1072 ///
1073 /// ```
32a655c1
SL
1074 /// use std::thread;
1075 ///
cc61c64b
XL
1076 /// let other_thread = thread::spawn(|| {
1077 /// thread::current().id()
1078 /// });
32a655c1 1079 ///
cc61c64b
XL
1080 /// let other_thread_id = other_thread.join().unwrap();
1081 /// assert!(thread::current().id() != other_thread_id);
32a655c1 1082 /// ```
7cac9316 1083 #[stable(feature = "thread_id", since = "1.19.0")]
c30ab7b3
SL
1084 pub fn id(&self) -> ThreadId {
1085 self.inner.id
1086 }
1087
9346a6ac 1088 /// Gets the thread's name.
3157f602 1089 ///
3b2f2976
XL
1090 /// For more information about named threads, see
1091 /// [this module-level documentation][naming-threads].
1092 ///
3157f602
XL
1093 /// # Examples
1094 ///
1095 /// Threads by default have no name specified:
1096 ///
1097 /// ```
1098 /// use std::thread;
1099 ///
1100 /// let builder = thread::Builder::new();
1101 ///
1102 /// let handler = builder.spawn(|| {
1103 /// assert!(thread::current().name().is_none());
1104 /// }).unwrap();
1105 ///
1106 /// handler.join().unwrap();
1107 /// ```
1108 ///
1109 /// Thread with a specified name:
1110 ///
1111 /// ```
1112 /// use std::thread;
1113 ///
1114 /// let builder = thread::Builder::new()
1115 /// .name("foo".into());
1116 ///
1117 /// let handler = builder.spawn(|| {
1118 /// assert_eq!(thread::current().name(), Some("foo"))
1119 /// }).unwrap();
1120 ///
1121 /// handler.join().unwrap();
1122 /// ```
3b2f2976
XL
1123 ///
1124 /// [naming-threads]: ./index.html#naming-threads
85aaf69f 1125 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1126 pub fn name(&self) -> Option<&str> {
54a0048b
SL
1127 self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) } )
1128 }
1129
1130 fn cname(&self) -> Option<&CStr> {
85aaf69f
SL
1131 self.inner.name.as_ref().map(|s| &**s)
1132 }
1133}
1134
1135#[stable(feature = "rust1", since = "1.0.0")]
1136impl fmt::Debug for Thread {
1137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1138 fmt::Debug::fmt(&self.name(), f)
1a4d82fc
JJ
1139 }
1140}
1141
c34b1796 1142////////////////////////////////////////////////////////////////////////////////
e9174d1e 1143// JoinHandle
c34b1796
AL
1144////////////////////////////////////////////////////////////////////////////////
1145
7cac9316
XL
1146/// A specialized [`Result`] type for threads.
1147///
1a4d82fc
JJ
1148/// Indicates the manner in which a thread exited.
1149///
1150/// A thread that completes without panicking is considered to exit successfully.
7cac9316
XL
1151///
1152/// # Examples
1153///
1154/// ```no_run
1155/// use std::thread;
1156/// use std::fs;
1157///
1158/// fn copy_in_thread() -> thread::Result<()> {
1159/// thread::spawn(move || { fs::copy("foo.txt", "bar.txt").unwrap(); }).join()
1160/// }
1161///
1162/// fn main() {
1163/// match copy_in_thread() {
1164/// Ok(_) => println!("this is fine"),
1165/// Err(_) => println!("thread panicked"),
1166/// }
1167/// }
1168/// ```
1169///
1170/// [`Result`]: ../../std/result/enum.Result.html
85aaf69f
SL
1171#[stable(feature = "rust1", since = "1.0.0")]
1172pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
1a4d82fc 1173
d9579d0f
AL
1174// This packet is used to communicate the return value between the child thread
1175// and the parent thread. Memory is shared through the `Arc` within and there's
1176// no need for a mutex here because synchronization happens with `join()` (the
1177// parent thread never reads this packet until the child has exited).
1178//
1179// This packet itself is then stored into a `JoinInner` which in turns is placed
1180// in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
1181// manually worry about impls like Send and Sync. The type `T` should
1182// already always be Send (otherwise the thread could not have been created) and
1183// this type is inherently Sync because no methods take &self. Regardless,
1184// however, we add inheriting impls for Send/Sync to this type to ensure it's
1185// Send/Sync and that future modifications will still appropriately classify it.
1a4d82fc
JJ
1186struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
1187
d9579d0f
AL
1188unsafe impl<T: Send> Send for Packet<T> {}
1189unsafe impl<T: Sync> Sync for Packet<T> {}
1a4d82fc 1190
e9174d1e 1191/// Inner representation for JoinHandle
85aaf69f 1192struct JoinInner<T> {
d9579d0f 1193 native: Option<imp::Thread>,
85aaf69f
SL
1194 thread: Thread,
1195 packet: Packet<T>,
85aaf69f
SL
1196}
1197
1198impl<T> JoinInner<T> {
1199 fn join(&mut self) -> Result<T> {
d9579d0f 1200 self.native.take().unwrap().join();
85aaf69f
SL
1201 unsafe {
1202 (*self.packet.0.get()).take().unwrap()
1203 }
1204 }
1205}
1206
1207/// An owned permission to join on a thread (block on its termination).
1208///
7cac9316
XL
1209/// A `JoinHandle` *detaches* the associated thread when it is dropped, which
1210/// means that there is no longer any handle to thread and no way to `join`
1211/// on it.
85aaf69f 1212///
32a655c1 1213/// Due to platform restrictions, it is not possible to [`Clone`] this
7cac9316 1214/// handle: the ability to join a thread is a uniquely-owned permission.
3157f602
XL
1215///
1216/// This `struct` is created by the [`thread::spawn`] function and the
1217/// [`thread::Builder::spawn`] method.
1218///
1219/// # Examples
1220///
1221/// Creation from [`thread::spawn`]:
1222///
32a655c1 1223/// ```
3157f602
XL
1224/// use std::thread;
1225///
1226/// let join_handle: thread::JoinHandle<_> = thread::spawn(|| {
1227/// // some work here
1228/// });
1229/// ```
1230///
1231/// Creation from [`thread::Builder::spawn`]:
1232///
32a655c1 1233/// ```
3157f602
XL
1234/// use std::thread;
1235///
1236/// let builder = thread::Builder::new();
1237///
1238/// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
1239/// // some work here
1240/// }).unwrap();
1241/// ```
1242///
7cac9316
XL
1243/// Child being detached and outliving its parent:
1244///
1245/// ```no_run
1246/// use std::thread;
1247/// use std::time::Duration;
1248///
1249/// let original_thread = thread::spawn(|| {
1250/// let _detached_thread = thread::spawn(|| {
1251/// // Here we sleep to make sure that the first thread returns before.
1252/// thread::sleep(Duration::from_millis(10));
1253/// // This will be called, even though the JoinHandle is dropped.
1254/// println!("♫ Still alive ♫");
1255/// });
1256/// });
1257///
abe05a73 1258/// original_thread.join().expect("The thread being joined has panicked");
7cac9316
XL
1259/// println!("Original thread is joined.");
1260///
1261/// // We make sure that the new thread has time to run, before the main
1262/// // thread returns.
1263///
1264/// thread::sleep(Duration::from_millis(1000));
1265/// ```
1266///
32a655c1 1267/// [`Clone`]: ../../std/clone/trait.Clone.html
3157f602
XL
1268/// [`thread::spawn`]: fn.spawn.html
1269/// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn
85aaf69f 1270#[stable(feature = "rust1", since = "1.0.0")]
9346a6ac 1271pub struct JoinHandle<T>(JoinInner<T>);
85aaf69f 1272
9346a6ac 1273impl<T> JoinHandle<T> {
32a655c1
SL
1274 /// Extracts a handle to the underlying thread.
1275 ///
1276 /// # Examples
1277 ///
1278 /// ```
32a655c1
SL
1279 /// use std::thread;
1280 ///
1281 /// let builder = thread::Builder::new();
1282 ///
1283 /// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
1284 /// // some work here
1285 /// }).unwrap();
1286 ///
1287 /// let thread = join_handle.thread();
1288 /// println!("thread id: {:?}", thread.id());
1289 /// ```
85aaf69f
SL
1290 #[stable(feature = "rust1", since = "1.0.0")]
1291 pub fn thread(&self) -> &Thread {
1292 &self.0.thread
1293 }
1294
9346a6ac 1295 /// Waits for the associated thread to finish.
85aaf69f 1296 ///
32a655c1
SL
1297 /// If the child thread panics, [`Err`] is returned with the parameter given
1298 /// to [`panic`].
1299 ///
1300 /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
1301 /// [`panic`]: ../../std/macro.panic.html
1302 ///
3b2f2976
XL
1303 /// # Panics
1304 ///
1305 /// This function may panic on some platforms if a thread attempts to join
1306 /// itself or otherwise may create a deadlock with joining threads.
1307 ///
32a655c1
SL
1308 /// # Examples
1309 ///
1310 /// ```
1311 /// use std::thread;
1312 ///
1313 /// let builder = thread::Builder::new();
1314 ///
1315 /// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
1316 /// // some work here
1317 /// }).unwrap();
1318 /// join_handle.join().expect("Couldn't join on the associated thread");
1319 /// ```
85aaf69f 1320 #[stable(feature = "rust1", since = "1.0.0")]
9346a6ac 1321 pub fn join(mut self) -> Result<T> {
85aaf69f
SL
1322 self.0.join()
1323 }
1324}
1325
92a42be0
SL
1326impl<T> AsInner<imp::Thread> for JoinHandle<T> {
1327 fn as_inner(&self) -> &imp::Thread { self.0.native.as_ref().unwrap() }
1328}
1329
1330impl<T> IntoInner<imp::Thread> for JoinHandle<T> {
1331 fn into_inner(self) -> imp::Thread { self.0.native.unwrap() }
1332}
1333
8bb4bdeb 1334#[stable(feature = "std_debug", since = "1.16.0")]
32a655c1
SL
1335impl<T> fmt::Debug for JoinHandle<T> {
1336 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1337 f.pad("JoinHandle { .. }")
1338 }
1339}
1340
d9579d0f
AL
1341fn _assert_sync_and_send() {
1342 fn _assert_both<T: Send + Sync>() {}
1343 _assert_both::<JoinHandle<()>>();
d9579d0f
AL
1344 _assert_both::<Thread>();
1345}
1346
c34b1796
AL
1347////////////////////////////////////////////////////////////////////////////////
1348// Tests
1349////////////////////////////////////////////////////////////////////////////////
1350
c30ab7b3 1351#[cfg(all(test, not(target_os = "emscripten")))]
d9579d0f 1352mod tests {
1a4d82fc
JJ
1353 use any::Any;
1354 use sync::mpsc::{channel, Sender};
1a4d82fc 1355 use result;
c34b1796 1356 use super::{Builder};
85aaf69f 1357 use thread;
85aaf69f 1358 use time::Duration;
c34b1796 1359 use u32;
1a4d82fc
JJ
1360
1361 // !!! These tests are dangerous. If something is buggy, they will hang, !!!
1362 // !!! instead of exiting cleanly. This might wedge the buildbots. !!!
1363
1364 #[test]
1365 fn test_unnamed_thread() {
85aaf69f
SL
1366 thread::spawn(move|| {
1367 assert!(thread::current().name().is_none());
1368 }).join().ok().unwrap();
1a4d82fc
JJ
1369 }
1370
1371 #[test]
1372 fn test_named_thread() {
e9174d1e 1373 Builder::new().name("ada lovelace".to_string()).spawn(move|| {
85aaf69f 1374 assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
e9174d1e 1375 }).unwrap().join().unwrap();
1a4d82fc
JJ
1376 }
1377
54a0048b
SL
1378 #[test]
1379 #[should_panic]
1380 fn test_invalid_named_thread() {
1381 let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {});
1382 }
1383
1a4d82fc
JJ
1384 #[test]
1385 fn test_run_basic() {
1386 let (tx, rx) = channel();
85aaf69f 1387 thread::spawn(move|| {
1a4d82fc
JJ
1388 tx.send(()).unwrap();
1389 });
1390 rx.recv().unwrap();
1391 }
1392
1a4d82fc
JJ
1393 #[test]
1394 fn test_join_panic() {
85aaf69f 1395 match thread::spawn(move|| {
1a4d82fc
JJ
1396 panic!()
1397 }).join() {
1398 result::Result::Err(_) => (),
1399 result::Result::Ok(()) => panic!()
1400 }
1401 }
1402
1403 #[test]
1404 fn test_spawn_sched() {
1a4d82fc
JJ
1405 let (tx, rx) = channel();
1406
c34b1796 1407 fn f(i: i32, tx: Sender<()>) {
1a4d82fc 1408 let tx = tx.clone();
85aaf69f 1409 thread::spawn(move|| {
1a4d82fc
JJ
1410 if i == 0 {
1411 tx.send(()).unwrap();
1412 } else {
1413 f(i - 1, tx);
1414 }
1415 });
1416
1417 }
1418 f(10, tx);
1419 rx.recv().unwrap();
1420 }
1421
1422 #[test]
1423 fn test_spawn_sched_childs_on_default_sched() {
1424 let (tx, rx) = channel();
1425
85aaf69f
SL
1426 thread::spawn(move|| {
1427 thread::spawn(move|| {
1a4d82fc
JJ
1428 tx.send(()).unwrap();
1429 });
1430 });
1431
1432 rx.recv().unwrap();
1433 }
1434
e9174d1e 1435 fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<Fn() + Send>) {
c34b1796 1436 let (tx, rx) = channel();
1a4d82fc 1437
c34b1796
AL
1438 let x: Box<_> = box 1;
1439 let x_in_parent = (&*x) as *const i32 as usize;
1a4d82fc 1440
c34b1796
AL
1441 spawnfn(Box::new(move|| {
1442 let x_in_child = (&*x) as *const i32 as usize;
1a4d82fc
JJ
1443 tx.send(x_in_child).unwrap();
1444 }));
1445
1446 let x_in_child = rx.recv().unwrap();
1447 assert_eq!(x_in_parent, x_in_child);
1448 }
1449
1450 #[test]
1451 fn test_avoid_copying_the_body_spawn() {
1452 avoid_copying_the_body(|v| {
c34b1796 1453 thread::spawn(move || v());
1a4d82fc
JJ
1454 });
1455 }
1456
1457 #[test]
1458 fn test_avoid_copying_the_body_thread_spawn() {
1459 avoid_copying_the_body(|f| {
85aaf69f 1460 thread::spawn(move|| {
c34b1796 1461 f();
1a4d82fc
JJ
1462 });
1463 })
1464 }
1465
1466 #[test]
1467 fn test_avoid_copying_the_body_join() {
1468 avoid_copying_the_body(|f| {
85aaf69f 1469 let _ = thread::spawn(move|| {
c34b1796 1470 f()
1a4d82fc
JJ
1471 }).join();
1472 })
1473 }
1474
1475 #[test]
1476 fn test_child_doesnt_ref_parent() {
bd371182
AL
1477 // If the child refcounts the parent thread, this will stack overflow when
1478 // climbing the thread tree to dereference each ancestor. (See #1789)
1a4d82fc
JJ
1479 // (well, it would if the constant were 8000+ - I lowered it to be more
1480 // valgrind-friendly. try this at home, instead..!)
c34b1796 1481 const GENERATIONS: u32 = 16;
e9174d1e 1482 fn child_no(x: u32) -> Box<Fn() + Send> {
c34b1796 1483 return Box::new(move|| {
1a4d82fc 1484 if x < GENERATIONS {
c34b1796 1485 thread::spawn(move|| child_no(x+1)());
1a4d82fc
JJ
1486 }
1487 });
1488 }
c34b1796 1489 thread::spawn(|| child_no(0)());
1a4d82fc
JJ
1490 }
1491
1492 #[test]
1493 fn test_simple_newsched_spawn() {
85aaf69f 1494 thread::spawn(move || {});
1a4d82fc
JJ
1495 }
1496
1497 #[test]
1498 fn test_try_panic_message_static_str() {
85aaf69f 1499 match thread::spawn(move|| {
1a4d82fc
JJ
1500 panic!("static string");
1501 }).join() {
1502 Err(e) => {
1503 type T = &'static str;
1504 assert!(e.is::<T>());
c34b1796 1505 assert_eq!(*e.downcast::<T>().unwrap(), "static string");
1a4d82fc
JJ
1506 }
1507 Ok(()) => panic!()
1508 }
1509 }
1510
1511 #[test]
1512 fn test_try_panic_message_owned_str() {
85aaf69f 1513 match thread::spawn(move|| {
1a4d82fc
JJ
1514 panic!("owned string".to_string());
1515 }).join() {
1516 Err(e) => {
1517 type T = String;
1518 assert!(e.is::<T>());
c34b1796 1519 assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
1a4d82fc
JJ
1520 }
1521 Ok(()) => panic!()
1522 }
1523 }
1524
1525 #[test]
1526 fn test_try_panic_message_any() {
85aaf69f 1527 match thread::spawn(move|| {
1a4d82fc
JJ
1528 panic!(box 413u16 as Box<Any + Send>);
1529 }).join() {
1530 Err(e) => {
1531 type T = Box<Any + Send>;
1532 assert!(e.is::<T>());
c34b1796 1533 let any = e.downcast::<T>().unwrap();
1a4d82fc 1534 assert!(any.is::<u16>());
c34b1796 1535 assert_eq!(*any.downcast::<u16>().unwrap(), 413);
1a4d82fc
JJ
1536 }
1537 Ok(()) => panic!()
1538 }
1539 }
1540
1541 #[test]
1542 fn test_try_panic_message_unit_struct() {
1543 struct Juju;
1544
85aaf69f 1545 match thread::spawn(move|| {
1a4d82fc
JJ
1546 panic!(Juju)
1547 }).join() {
1548 Err(ref e) if e.is::<Juju>() => {}
1549 Err(_) | Ok(()) => panic!()
1550 }
1551 }
1552
85aaf69f
SL
1553 #[test]
1554 fn test_park_timeout_unpark_before() {
1555 for _ in 0..10 {
1556 thread::current().unpark();
9cc50fc6 1557 thread::park_timeout(Duration::from_millis(u32::MAX as u64));
85aaf69f
SL
1558 }
1559 }
1560
1561 #[test]
1562 fn test_park_timeout_unpark_not_called() {
1563 for _ in 0..10 {
9cc50fc6 1564 thread::park_timeout(Duration::from_millis(10));
85aaf69f
SL
1565 }
1566 }
1567
1568 #[test]
1569 fn test_park_timeout_unpark_called_other_thread() {
85aaf69f
SL
1570 for _ in 0..10 {
1571 let th = thread::current();
1572
1573 let _guard = thread::spawn(move || {
9cc50fc6 1574 super::sleep(Duration::from_millis(50));
85aaf69f
SL
1575 th.unpark();
1576 });
1577
9cc50fc6 1578 thread::park_timeout(Duration::from_millis(u32::MAX as u64));
85aaf69f
SL
1579 }
1580 }
1581
c34b1796
AL
1582 #[test]
1583 fn sleep_ms_smoke() {
9cc50fc6 1584 thread::sleep(Duration::from_millis(2));
c34b1796
AL
1585 }
1586
c30ab7b3
SL
1587 #[test]
1588 fn test_thread_id_equal() {
1589 assert!(thread::current().id() == thread::current().id());
1590 }
1591
1592 #[test]
1593 fn test_thread_id_not_equal() {
1594 let spawned_id = thread::spawn(|| thread::current().id()).join().unwrap();
1595 assert!(thread::current().id() != spawned_id);
1596 }
1597
bd371182 1598 // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due
1a4d82fc
JJ
1599 // to the test harness apparently interfering with stderr configuration.
1600}