diff options
Diffstat (limited to 'library/std/src/thread/mod.rs')
| -rw-r--r-- | library/std/src/thread/mod.rs | 32 |
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", ) |
