summary refs log tree commit diff
path: root/library/std/src/thread/mod.rs
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2024-03-31 11:28:24 +0200
committerjoboet <jonasboettiger@icloud.com>2024-03-31 11:28:24 +0200
commit76684181018640df1769604cd92ed6beb30a27d6 (patch)
tree3acae87f5ed8d387c023f5ea8fd83f4854df1cb5 /library/std/src/thread/mod.rs
parent5b9d7ab558fe6ee53bd40e16a20c25716f3c9e56 (diff)
downloadrust-76684181018640df1769604cd92ed6beb30a27d6.tar.gz
rust-76684181018640df1769604cd92ed6beb30a27d6.zip
std: move `thread::current` TLS variable out of `thread_info`
Diffstat (limited to 'library/std/src/thread/mod.rs')
-rw-r--r--library/std/src/thread/mod.rs32
1 files changed, 24 insertions, 8 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 85de2980133..f7eb92bc61e 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::UnsafeCell;
+use crate::cell::{OnceCell, UnsafeCell};
 use crate::ffi::{CStr, CString};
 use crate::fmt;
 use crate::io;
@@ -174,7 +174,6 @@ use crate::str;
 use crate::sync::Arc;
 use crate::sys::thread as imp;
 use crate::sys_common::thread;
-use crate::sys_common::thread_info;
 use crate::sys_common::thread_parking::Parker;
 use crate::sys_common::{AsInner, IntoInner};
 use crate::time::{Duration, Instant};
@@ -518,12 +517,8 @@ impl Builder {
 
             crate::io::set_output_capture(output_capture);
 
-            // SAFETY: we constructed `f` initialized.
             let f = f.into_inner();
-            // SAFETY: the stack guard passed is the one for the current thread.
-            // This means the current thread's stack and the new thread's stack
-            // are properly set and protected from each other.
-            thread_info::set(unsafe { imp::guard::current() }, their_thread);
+            set_current(their_thread);
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                 crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
             }));
@@ -683,6 +678,27 @@ where
     Builder::new().spawn(f).expect("failed to spawn thread")
 }
 
+thread_local! {
+    static CURRENT: OnceCell<Thread> = const { OnceCell::new() };
+}
+
+/// Sets the thread handle for the current thread.
+///
+/// Panics if the handle has been set already or when called from a TLS destructor.
+pub(crate) fn set_current(thread: Thread) {
+    CURRENT.with(|current| current.set(thread).unwrap());
+}
+
+/// Gets a handle to the thread that invokes it.
+///
+/// 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(imp::Thread::get_name())).clone())
+        .ok()
+}
+
 /// Gets a handle to the thread that invokes it.
 ///
 /// # Examples
@@ -705,7 +721,7 @@ where
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn current() -> Thread {
-    thread_info::current_thread().expect(
+    try_current().expect(
         "use of std::thread::current() is not possible \
          after the thread's local data has been destroyed",
     )