| 1 | use super::id::ThreadId; |
| 2 | use super::main_thread; |
| 3 | use crate::alloc::System; |
| 4 | use crate::ffi::CStr; |
| 5 | use crate::fmt; |
| 6 | use crate::pin::Pin; |
| 7 | use crate::sync::Arc; |
| 8 | use crate::sys::sync::Parker; |
| 9 | use crate::time::Duration; |
| 10 | |
| 11 | // This module ensures private fields are kept private, which is necessary to enforce the safety requirements. |
| 12 | mod 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 | |
| 41 | use 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))] |
| 49 | struct Inner { |
| 50 | name: Option<ThreadNameString>, |
| 51 | id: ThreadId, |
| 52 | parker: Parker, |
| 53 | } |
| 54 | |
| 55 | impl 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 |
| 85 | pub 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 | |
| 92 | impl 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" )] |
| 319 | impl 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 | } |
| 327 | |