diff options
| author | bors <bors@rust-lang.org> | 2024-07-18 18:12:47 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-18 18:12:47 +0000 |
| commit | 5affbb17153bc69a9d5d8d2faa4e399a014a211e (patch) | |
| tree | 2e6bc66041b6eaf30a44511671197ac4cf4c98ba /library/std/src/thread/mod.rs | |
| parent | 5753b3067662e17a69b54b9418dbc37b73769a84 (diff) | |
| parent | 6c108224e11e3c21f68dd416f70950e9cc529799 (diff) | |
| download | rust-5affbb17153bc69a9d5d8d2faa4e399a014a211e.tar.gz rust-5affbb17153bc69a9d5d8d2faa4e399a014a211e.zip | |
Auto merge of #127924 - matthiaskrgr:rollup-1gn6afv, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #124881 (Use ThreadId instead of TLS-address in `ReentrantLock`) - #127656 (make pub_use_of_private_extern_crate show up in cargo's future breakage reports) - #127748 (Use Option's discriminant as its size hint) - #127854 (Add internal lint for detecting non-glob imports of `rustc_type_ir::inherent`) - #127908 (Update extern linking documentation) - #127919 (Allow a git command for getting the current branch in bootstrap to fail) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src/thread/mod.rs')
| -rw-r--r-- | library/std/src/thread/mod.rs | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index c8ee365392f..7b98f2ae763 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -159,7 +159,7 @@ mod tests; use crate::any::Any; -use crate::cell::{OnceCell, UnsafeCell}; +use crate::cell::{Cell, OnceCell, UnsafeCell}; use crate::env; use crate::ffi::{CStr, CString}; use crate::fmt; @@ -699,17 +699,22 @@ where } thread_local! { + // Invariant: `CURRENT` and `CURRENT_ID` will always be initialized together. + // If `CURRENT` is initialized, then `CURRENT_ID` will hold the same value + // as `CURRENT.id()`. static CURRENT: OnceCell<Thread> = const { OnceCell::new() }; + static CURRENT_ID: Cell<Option<ThreadId>> = const { Cell::new(None) }; } /// Sets the thread handle for the current thread. /// /// Aborts if the handle has been set already to reduce code size. pub(crate) fn set_current(thread: Thread) { + let tid = thread.id(); // Using `unwrap` here can add ~3kB to the binary size. We have complete // control over where this is called, so just abort if there is a bug. CURRENT.with(|current| match current.set(thread) { - Ok(()) => {} + Ok(()) => CURRENT_ID.set(Some(tid)), Err(_) => rtabort!("thread::set_current should only be called once per thread"), }); } @@ -719,7 +724,28 @@ pub(crate) fn set_current(thread: Thread) { /// In contrast to the public `current` function, this will not panic if called /// from inside a TLS destructor. pub(crate) fn try_current() -> Option<Thread> { - CURRENT.try_with(|current| current.get_or_init(|| Thread::new_unnamed()).clone()).ok() + CURRENT + .try_with(|current| { + current + .get_or_init(|| { + let thread = Thread::new_unnamed(); + CURRENT_ID.set(Some(thread.id())); + thread + }) + .clone() + }) + .ok() +} + +/// Gets the id of the thread that invokes it. +#[inline] +pub(crate) fn current_id() -> ThreadId { + CURRENT_ID.get().unwrap_or_else(|| { + // If `CURRENT_ID` isn't initialized yet, then `CURRENT` must also not be initialized. + // `current()` will initialize both `CURRENT` and `CURRENT_ID` so subsequent calls to + // `current_id()` will succeed immediately. + current().id() + }) } /// Gets a handle to the thread that invokes it. |
