//! The [`thread::current`] function is available even for threads not spawned
//! by the APIs of this module.
//!
-//! ## Blocking support: park and unpark
-//!
-//! Every thread is equipped with some basic low-level blocking support, via the
-//! [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`]
-//! method. [`park`] blocks the current thread, which can then be resumed from
-//! another thread by calling the [`unpark`] method on the blocked thread's handle.
-//!
-//! Conceptually, each [`Thread`] handle has an associated token, which is
-//! initially not present:
-//!
-//! * The [`thread::park`][`park`] function blocks the current thread unless or until
-//! the token is available for its thread handle, at which point it atomically
-//! consumes the token. It may also return *spuriously*, without consuming the
-//! token. [`thread::park_timeout`] does the same, but allows specifying a
-//! maximum time to block the thread for.
-//!
-//! * The [`unpark`] method on a [`Thread`] atomically makes the token available
-//! if it wasn't already.
-//!
-//! In other words, each [`Thread`] acts a bit like a semaphore with initial count
-//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
-//! and can return spuriously.
-//!
-//! The API is typically used by acquiring a handle to the current thread,
-//! placing that handle in a shared data structure so that other threads can
-//! find it, and then `park`ing. When some desired condition is met, another
-//! thread calls [`unpark`] on the handle.
-//!
-//! The motivation for this design is twofold:
-//!
-//! * It avoids the need to allocate mutexes and condvars when building new
-//! synchronization primitives; the threads already provide basic blocking/signaling.
-//!
-//! * It can be implemented very efficiently on many platforms.
-//!
//! ## Thread-local storage
//!
//! This module also provides an implementation of thread-local storage for Rust
/// Generates the base configuration for spawning a thread, from which
/// configuration methods can be chained.
///
+ /// If the [`stack_size`] field is not specified, the stack size
+ /// will be the `RUST_MIN_STACK` environment variable, if it is
+ /// not specified either, a sensible default size will be set (2MB as
+ /// of the writting of this doc).
+ ///
/// # Examples
///
/// ```
///
/// handler.join().unwrap();
/// ```
+ ///
+ /// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> Builder {
Builder {
}
unsafe {
thread_info::set(imp::guard::current(), their_thread);
- let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
+ let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+ ::sys_common::backtrace::__rust_begin_short_backtrace(f)
+ }));
*their_packet.get() = Some(try_result);
}
};
/// Determines whether the current thread is unwinding because of panic.
///
+/// A common use of this feature is to poison shared resources when writing
+/// unsafe code, by checking `panicking` when the `drop` is called.
+///
+/// This is usually not needed when writing safe code, as [`Mutex`es][Mutex]
+/// 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
+/// monitoring purposes).
+///
/// # Examples
///
/// ```should_panic
/// panic!()
/// }
/// ```
+///
+/// [Mutex]: ../../std/sync/struct.Mutex.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn panicking() -> bool {
/// Blocks unless or until the current thread's token is made available.
///
-/// Every thread is equipped with some basic low-level blocking support, via
-/// the `park()` function and the [`unpark`][unpark] method. These can be
-/// used as a more CPU-efficient implementation of a spinlock.
+/// A call to `park` does not guarantee that the thread will remain parked
+/// forever, and callers should be prepared for this possibility.
+///
+/// # park and unpark
+///
+/// Every thread is equipped with some basic low-level blocking support, via the
+/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`]
+/// method. [`park`] blocks the current thread, which can then be resumed from
+/// another thread by calling the [`unpark`] method on the blocked thread's
+/// handle.
///
-/// [unpark]: struct.Thread.html#method.unpark
+/// Conceptually, each [`Thread`] handle has an associated token, which is
+/// initially not present:
+///
+/// * The [`thread::park`][`park`] function blocks the current thread unless or
+/// until the token is available for its thread handle, at which point it
+/// atomically consumes the token. It may also return *spuriously*, without
+/// consuming the token. [`thread::park_timeout`] does the same, but allows
+/// specifying a maximum time to block the thread for.
+///
+/// * The [`unpark`] method on a [`Thread`] atomically makes the token available
+/// if it wasn't already.
+///
+/// In other words, each [`Thread`] acts a bit like a spinlock that can be
+/// locked and unlocked using `park` and `unpark`.
///
/// The API is typically used by acquiring a handle to the current thread,
/// placing that handle in a shared data structure so that other threads can
-/// find it, and then parking (in a loop with a check for the token actually
-/// being acquired).
+/// find it, and then `park`ing. When some desired condition is met, another
+/// thread calls [`unpark`] on the handle.
///
-/// A call to `park` does not guarantee that the thread will remain parked
-/// forever, and callers should be prepared for this possibility.
+/// The motivation for this design is twofold:
+///
+/// * It avoids the need to allocate mutexes and condvars when building new
+/// synchronization primitives; the threads already provide basic
+/// blocking/signaling.
///
-/// See the [module documentation][thread] for more detail.
+/// * It can be implemented very efficiently on many platforms.
///
-/// [thread]: index.html
+/// # Examples
+///
+/// ```
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let parked_thread = thread::Builder::new()
+/// .spawn(|| {
+/// println!("Parking thread");
+/// thread::park();
+/// println!("Thread unparked");
+/// })
+/// .unwrap();
+///
+/// // Let some time pass for the thread to be spawned.
+/// thread::sleep(Duration::from_millis(10));
+///
+/// println!("Unpark the thread");
+/// parked_thread.thread().unpark();
+///
+/// parked_thread.join().unwrap();
+/// ```
+///
+/// [`Thread`]: ../../std/thread/struct.Thread.html
+/// [`park`]: ../../std/thread/fn.park.html
+/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
+/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
//
// The implementation currently uses the trivial strategy of a Mutex+Condvar
// with wakeup flag, which does not actually allow spurious wakeups. In the
*guard = false;
}
-/// Use [park_timeout].
+/// Use [`park_timeout`].
///
/// Blocks unless or until the current thread's token is made available or
/// the specified duration has been reached (may wake spuriously).
///
-/// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than `ms`. This method
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`] except
+/// that the thread will be blocked for roughly no longer than `dur`. This
+/// method should not be used for precise timing due to anomalies such as
/// preemption or platform differences that may not cause the maximum
/// amount of time waited to be precisely `ms` long.
///
-/// See the [module documentation][thread] for more detail.
+/// See the [park documentation][`park`] for more detail.
///
-/// [thread]: index.html
-/// [park_timeout]: fn.park_timeout.html
+/// [`park_timeout`]: fn.park_timeout.html
+/// [`park`]: ../../std/thread/fn.park.html
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
pub fn park_timeout_ms(ms: u32) {
/// Blocks unless or until the current thread's token is made available or
/// the specified duration has been reached (may wake spuriously).
///
-/// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than `dur`. This method
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`][park] except
+/// that the thread will be blocked for roughly no longer than `dur`. This
+/// method should not be used for precise timing due to anomalies such as
/// preemption or platform differences that may not cause the maximum
/// amount of time waited to be precisely `dur` long.
///
-/// See the module doc for more detail.
+/// See the [park dococumentation][park] for more details.
///
/// # Platform behavior
///
/// park_timeout(timeout);
/// }
/// ```
+///
+/// [park]: fn.park.html
#[stable(feature = "park_timeout", since = "1.4.0")]
pub fn park_timeout(dur: Duration) {
let thread = current();
#[stable(feature = "rust1", since = "1.0.0")]
/// A handle to a thread.
///
-/// You can use it to identify a thread (by name, for example). Most of the
-/// time, there is no need to directly create a `Thread` struct using the
-/// constructor, instead you should use a function like `spawn` to create
-/// new threads, see the docs of [`Builder`] and [`spawn`] for more.
+/// Threads are represented via the `Thread` type, which you can get in one of
+/// two ways:
///
-/// # Examples
+/// * 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.
+///
+/// The [`thread::current`] function is available even for threads not spawned
+/// by the APIs of this module.
+///
+/// There is usualy no need to create a `Thread` struct yourself, one
+/// should instead use a function like `spawn` to create new threads, see the
+/// docs of [`Builder`] and [`spawn`] for more details.
///
-/// ```no_run
-/// # // Note that this example isn't executed by default because it causes
-/// # // deadlocks on Windows unfortunately (see #25824)
-/// use std::thread::Builder;
-///
-/// for i in 0..5 {
-/// let thread_name = format!("thread_{}", i);
-/// Builder::new()
-/// .name(thread_name) // Now you can identify which thread panicked
-/// // thanks to the handle's name
-/// .spawn(move || {
-/// if i == 3 {
-/// panic!("I'm scared!!!");
-/// }
-/// })
-/// .unwrap();
-/// }
-/// ```
/// [`Builder`]: ../../std/thread/struct.Builder.html
/// [`spawn`]: ../../std/thread/fn.spawn.html
/// Atomically makes the handle's token available if it is not already.
///
- /// See the module doc for more detail.
+ /// Every thread is equipped with some basic low-level blocking support, via
+ /// the [`park`][park] function and the `unpark()` method. These can be
+ /// used as a more CPU-efficient implementation of a spinlock.
+ ///
+ /// See the [park documentation][park] for more details.
///
/// # Examples
///
/// ```
/// use std::thread;
+ /// use std::time::Duration;
///
- /// let handler = thread::Builder::new()
+ /// let parked_thread = thread::Builder::new()
/// .spawn(|| {
- /// let thread = thread::current();
- /// thread.unpark();
+ /// println!("Parking thread");
+ /// thread::park();
+ /// println!("Thread unparked");
/// })
/// .unwrap();
///
- /// handler.join().unwrap();
+ /// // Let some time pass for the thread to be spawned.
+ /// thread::sleep(Duration::from_millis(10));
+ ///
+ /// println!("Unpark the thread");
+ /// parked_thread.thread().unpark();
+ ///
+ /// parked_thread.join().unwrap();
/// ```
+ ///
+ /// [park]: fn.park.html
#[stable(feature = "rust1", since = "1.0.0")]
pub fn unpark(&self) {
let mut guard = self.inner.lock.lock().unwrap();