about summary refs log tree commit diff
path: root/library/std/src/thread/mod.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-18 18:12:47 +0000
committerbors <bors@rust-lang.org>2024-07-18 18:12:47 +0000
commit5affbb17153bc69a9d5d8d2faa4e399a014a211e (patch)
tree2e6bc66041b6eaf30a44511671197ac4cf4c98ba /library/std/src/thread/mod.rs
parent5753b3067662e17a69b54b9418dbc37b73769a84 (diff)
parent6c108224e11e3c21f68dd416f70950e9cc529799 (diff)
downloadrust-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.rs32
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.