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}