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

#
std/thread/
main_thread.rs

    1//! Store the ID of the main thread.
    2//!
    3//! The thread handle for the main thread is created lazily, and this might even
    4//! happen pre-main. Since not every platform has a way to identify the main
    5//! thread when that happens – macOS's `pthread_main_np` function being a notable
    6//! exception – we cannot assign it the right name right then. Instead, in our
    7//! runtime startup code, we remember the thread ID of the main thread (through
    8//! this modules `set` function) and use it to identify the main thread from then
    9//! on. This works reliably and has the additional advantage that we can report
    10//! the right thread name on main even after the thread handle has been destroyed.
    11//! Note however that this also means that the name reported in pre-main functions
    12//! will be incorrect, but that's just something we have to live with.
    13
    14cfg_select! {
    15    target_has_atomic = "64" => {
    16        use super::id::ThreadId;
    17        use crate::sync::atomic::{Atomic, AtomicU64};
    18        use crate::sync::atomic::Ordering::Relaxed;
    19
    20        static MAIN: Atomic<u64> = AtomicU64::new(0);
    21
    22        pub(super) fn get() -> Option<ThreadId> {
    23            ThreadId::from_u64(MAIN.load(Relaxed))
    24        }
    25
    26        /// # Safety
    27        /// May only be called once.
    28        pub(crate) unsafe fn set(id: ThreadId) {
    29            MAIN.store(id.as_u64().get(), Relaxed)
    30        }
    31    }
    32    _ => {
    33        use super::id::ThreadId;
    34        use crate::mem::MaybeUninit;
    35        use crate::sync::atomic::{Atomic, AtomicBool};
    36        use crate::sync::atomic::Ordering::{Acquire, Release};
    37
    38        static INIT: Atomic<bool> = AtomicBool::new(false);
    39        static mut MAIN: MaybeUninit<ThreadId> = MaybeUninit::uninit();
    40
    41        pub(super) fn get() -> Option<ThreadId> {
    42            if INIT.load(Acquire) {
    43                Some(unsafe { MAIN.assume_init() })
    44            } else {
    45                None
    46            }
    47        }
    48
    49        /// # Safety
    50        /// May only be called once.
    51        pub(crate) unsafe fn set(id: ThreadId) {
    52            unsafe { MAIN = MaybeUninit::new(id) };
    53            INIT.store(true, Release);
    54        }
    55    }
    56}