thread.rs - source
Description: Source of the Rust file `library/std/src/thread/thread.rs`.

#
std/thread/
thread.rs

    1use super::id::ThreadId;
    2use super::main_thread;
    3use crate::alloc::System;
    4use crate::ffi::CStr;
    5use crate::fmt;
    6use crate::pin::Pin;
    7use crate::sync::Arc;
    8use crate::sys::sync::Parker;
    9use crate::time::Duration;
    10
    11// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
    12mod thread_name_string {
    13    use crate::ffi::{CStr, CString};
    14    use crate::str;
    15
    16    /// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
    17    pub(crate) struct ThreadNameString {
    18        inner: CString,
    19    }
    20
    21    impl From<String> for ThreadNameString {
    22        fn from(s: String) -> Self {
    23            Self {
    24                inner: CString::new(s).expect("thread name may not contain interior null bytes"),
    25            }
    26        }
    27    }
    28
    29    impl ThreadNameString {
    30        pub fn as_cstr(&self) -> &CStr {
    31            &self.inner
    32        }
    33
    34        pub fn as_str(&self) -> &str {
    35            // SAFETY: `ThreadNameString` is guaranteed to be UTF-8.
    36            unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) }
    37        }
    38    }
    39}
    40
    41use thread_name_string::ThreadNameString;
    42
    43/// The internal representation of a `Thread` handle
    44///
    45/// We explicitly set the alignment for our guarantee in Thread::into_raw. This
    46/// allows applications to stuff extra metadata bits into the alignment, which
    47/// can be rather useful when working with atomics.
    48#[repr(align(8))]
    49struct Inner {
    50    name: Option<ThreadNameString>,
    51    id: ThreadId,
    52    parker: Parker,
    53}
    54
    55impl Inner {
    56    fn parker(self: Pin<&Self>) -> Pin<&Parker> {
    57        unsafe { Pin::map_unchecked(self, |inner| &inner.parker) }
    58    }
    59}
    60
    61#[derive(Clone)]
    62#[stable(feature = "rust1", since = "1.0.0")]
    63/// A handle to a thread.
    64///
    65/// Threads are represented via the `Thread` type, which you can get in one of
    66/// two ways:
    67///
    68/// * By spawning a new thread, e.g., using the [`thread::spawn`]
    69///   function, and calling [`thread`] on the [`JoinHandle`].
    70/// * By requesting the current thread, using the [`thread::current`] function.
    71///
    72/// The [`thread::current`] function is available even for threads not spawned
    73/// by the APIs of this module.
    74///
    75/// There is usually no need to create a `Thread` struct yourself, one
    76/// should instead use a function like `spawn` to create new threads, see the
    77/// docs of [`Builder`] and [`spawn`] for more details.
    78///
    79/// [`thread::spawn`]: super::spawn
    80/// [`thread`]: super::JoinHandle::thread
    81/// [`JoinHandle`]: super::JoinHandle
    82/// [`thread::current`]: super::current::current
    83/// [`Builder`]: super::Builder
    84/// [`spawn`]: super::spawn
    85pub struct Thread {
    86    // We use the System allocator such that creating or dropping this handle
    87    // does not interfere with a potential Global allocator using thread-local
    88    // storage.
    89    inner: Pin<Arc<Inner, System>>,
    90}
    91
    92impl Thread {
    93    pub(crate) fn new(id: ThreadId, name: Option<String>) -> Thread {
    94        let name = name.map(ThreadNameString::from);
    95
    96        // We have to use `unsafe` here to construct the `Parker` in-place,
    97        // which is required for the UNIX implementation.
    98        //
    99        // SAFETY: We pin the Arc immediately after creation, so its address never
    100        // changes.
    101        let inner = unsafe {
    102            let mut arc = Arc::<Inner, _>::new_uninit_in(System);
    103            let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
    104            (&raw mut (*ptr).name).write(name);
    105            (&raw mut (*ptr).id).write(id);
    106            Parker::new_in_place(&raw mut (*ptr).parker);
    107            Pin::new_unchecked(arc.assume_init())
    108        };
    109
    110        Thread { inner }
    111    }
    112
    113    /// Like the public [`park`], but callable on any handle. This is used to
    114    /// allow parking in TLS destructors.
    115    ///
    116    /// # Safety
    117    /// May only be called from the thread to which this handle belongs.
    118    ///
    119    /// [`park`]: super::park
    120    pub(crate) unsafe fn park(&self) {
    121        unsafe { self.inner.as_ref().parker().park() }
    122    }
    123
    124    /// Like the public [`park_timeout`], but callable on any handle. This is
    125    /// used to allow parking in TLS destructors.
    126    ///
    127    /// # Safety
    128    /// May only be called from the thread to which this handle belongs.
    129    ///
    130    /// [`park_timeout`]: super::park_timeout
    131    pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
    132        unsafe { self.inner.as_ref().parker().park_timeout(dur) }
    133    }
    134
    135    /// Atomically makes the handle's token available if it is not already.
    136    ///
    137    /// Every thread is equipped with some basic low-level blocking support, via
    138    /// the [`park`] function and the `unpark()` method. These can be used as a
    139    /// more CPU-efficient implementation of a spinlock.
    140    ///
    141    /// See the [park documentation] for more details.
    142    ///
    143    /// # Examples
    144    ///
    145    /// ```
    146    /// use std::thread;
    147    /// use std::time::Duration;
    148    /// use std::sync::atomic::{AtomicBool, Ordering};
    149    ///
    150    /// static QUEUED: AtomicBool = AtomicBool::new(false);
    151    ///
    152    /// let parked_thread = thread::Builder::new()
    153    ///     .spawn(|| {
    154    ///         println!("Parking thread");
    155    ///         QUEUED.store(true, Ordering::Release);
    156    ///         thread::park();
    157    ///         println!("Thread unparked");
    158    ///     })
    159    ///     .unwrap();
    160    ///
    161    /// // Let some time pass for the thread to be spawned.
    162    /// thread::sleep(Duration::from_millis(10));
    163    ///
    164    /// // Wait until the other thread is queued.
    165    /// // This is crucial! It guarantees that the `unpark` below is not consumed
    166    /// // by some other code in the parked thread (e.g. inside `println!`).
    167    /// while !QUEUED.load(Ordering::Acquire) {
    168    ///     // Spinning is of course inefficient; in practice, this would more likely be
    169    ///     // a dequeue where we have no work to do if there's nobody queued.
    170    ///     std::hint::spin_loop();
    171    /// }
    172    ///
    173    /// println!("Unpark the thread");
    174    /// parked_thread.thread().unpark();
    175    ///
    176    /// parked_thread.join().unwrap();
    177    /// ```
    178    ///
    179    /// [`park`]: super::park
    180    /// [park documentation]: super::park
    181    #[stable(feature = "rust1", since = "1.0.0")]
    182    #[inline]
    183    pub fn unpark(&self) {
    184        self.inner.as_ref().parker().unpark();
    185    }
    186
    187    /// Gets the thread's unique identifier.
    188    ///
    189    /// # Examples
    190    ///
    191    /// ```
    192    /// use std::thread;
    193    ///
    194    /// let other_thread = thread::spawn(|| {
    195    ///     thread::current().id()
    196    /// });
    197    ///
    198    /// let other_thread_id = other_thread.join().unwrap();
    199    /// assert!(thread::current().id() != other_thread_id);
    200    /// ```
    201    #[stable(feature = "thread_id", since = "1.19.0")]
    202    #[must_use]
    203    pub fn id(&self) -> ThreadId {
    204        self.inner.id
    205    }
    206
    207    /// Gets the thread's name.
    208    ///
    209    /// For more information about named threads, see
    210    /// [this module-level documentation][naming-threads].
    211    ///
    212    /// # Examples
    213    ///
    214    /// Threads by default have no name specified:
    215    ///
    216    /// ```
    217    /// use std::thread;
    218    ///
    219    /// let builder = thread::Builder::new();
    220    ///
    221    /// let handler = builder.spawn(|| {
    222    ///     assert!(thread::current().name().is_none());
    223    /// }).unwrap();
    224    ///
    225    /// handler.join().unwrap();
    226    /// ```
    227    ///
    228    /// Thread with a specified name:
    229    ///
    230    /// ```
    231    /// use std::thread;
    232    ///
    233    /// let builder = thread::Builder::new()
    234    ///     .name("foo".into());
    235    ///
    236    /// let handler = builder.spawn(|| {
    237    ///     assert_eq!(thread::current().name(), Some("foo"))
    238    /// }).unwrap();
    239    ///
    240    /// handler.join().unwrap();
    241    /// ```
    242    ///
    243    /// [naming-threads]: ./index.html#naming-threads
    244    #[stable(feature = "rust1", since = "1.0.0")]
    245    #[must_use]
    246    pub fn name(&self) -> Option<&str> {
    247        if let Some(name) = &self.inner.name {
    248            Some(name.as_str())
    249        } else if main_thread::get() == Some(self.inner.id) {
    250            Some("main")
    251        } else {
    252            None
    253        }
    254    }
    255
    256    /// Consumes the `Thread`, returning a raw pointer.
    257    ///
    258    /// To avoid a memory leak the pointer must be converted
    259    /// back into a `Thread` using [`Thread::from_raw`]. The pointer is
    260    /// guaranteed to be aligned to at least 8 bytes.
    261    ///
    262    /// # Examples
    263    ///
    264    /// ```
    265    /// #![feature(thread_raw)]
    266    ///
    267    /// use std::thread::{self, Thread};
    268    ///
    269    /// let thread = thread::current();
    270    /// let id = thread.id();
    271    /// let ptr = Thread::into_raw(thread);
    272    /// unsafe {
    273    ///     assert_eq!(Thread::from_raw(ptr).id(), id);
    274    /// }
    275    /// ```
    276    #[unstable(feature = "thread_raw", issue = "97523")]
    277    pub fn into_raw(self) -> *const () {
    278        // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
    279        let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
    280        Arc::into_raw_with_allocator(inner).0 as *const ()
    281    }
    282
    283    /// Constructs a `Thread` from a raw pointer.
    284    ///
    285    /// The raw pointer must have been previously returned
    286    /// by a call to [`Thread::into_raw`].
    287    ///
    288    /// # Safety
    289    ///
    290    /// This function is unsafe because improper use may lead
    291    /// to memory unsafety, even if the returned `Thread` is never
    292    /// accessed.
    293    ///
    294    /// Creating a `Thread` from a pointer other than one returned
    295    /// from [`Thread::into_raw`] is **undefined behavior**.
    296    ///
    297    /// Calling this function twice on the same raw pointer can lead
    298    /// to a double-free if both `Thread` instances are dropped.
    299    #[unstable(feature = "thread_raw", issue = "97523")]
    300    pub unsafe fn from_raw(ptr: *const ()) -> Thread {
    301        // Safety: Upheld by caller.
    302        unsafe {
    303            Thread { inner: Pin::new_unchecked(Arc::from_raw_in(ptr as *const Inner, System)) }
    304        }
    305    }
    306
    307    pub(crate) fn cname(&self) -> Option<&CStr> {
    308        if let Some(name) = &self.inner.name {
    309            Some(name.as_cstr())
    310        } else if main_thread::get() == Some(self.inner.id) {
    311            Some(c"main")
    312        } else {
    313            None
    314        }
    315    }
    316}
    317
    318#[stable(feature = "rust1", since = "1.0.0")]
    319impl fmt::Debug for Thread {
    320    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    321        f.debug_struct("Thread")
    322            .field("id", &self.id())
    323            .field("name", &self.name())
    324            .finish_non_exhaustive()
    325    }
    326}