159
159
mod tests;
160
160
161
161
use crate :: any:: Any ;
162
- use crate :: cell:: UnsafeCell ;
162
+ use crate :: cell:: { OnceCell , UnsafeCell } ;
163
163
use crate :: ffi:: { CStr , CString } ;
164
164
use crate :: fmt;
165
165
use crate :: io;
@@ -174,7 +174,6 @@ use crate::str;
174
174
use crate :: sync:: Arc ;
175
175
use crate :: sys:: thread as imp;
176
176
use crate :: sys_common:: thread;
177
- use crate :: sys_common:: thread_info;
178
177
use crate :: sys_common:: thread_parking:: Parker ;
179
178
use crate :: sys_common:: { AsInner , IntoInner } ;
180
179
use crate :: time:: { Duration , Instant } ;
@@ -518,12 +517,8 @@ impl Builder {
518
517
519
518
crate :: io:: set_output_capture ( output_capture) ;
520
519
521
- // SAFETY: we constructed `f` initialized.
522
520
let f = f. into_inner ( ) ;
523
- // SAFETY: the stack guard passed is the one for the current thread.
524
- // This means the current thread's stack and the new thread's stack
525
- // are properly set and protected from each other.
526
- thread_info:: set ( unsafe { imp:: guard:: current ( ) } , their_thread) ;
521
+ set_current ( their_thread) ;
527
522
let try_result = panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
528
523
crate :: sys_common:: backtrace:: __rust_begin_short_backtrace ( f)
529
524
} ) ) ;
@@ -683,6 +678,27 @@ where
683
678
Builder :: new ( ) . spawn ( f) . expect ( "failed to spawn thread" )
684
679
}
685
680
681
+ thread_local ! {
682
+ static CURRENT : OnceCell <Thread > = const { OnceCell :: new( ) } ;
683
+ }
684
+
685
+ /// Sets the thread handle for the current thread.
686
+ ///
687
+ /// Panics if the handle has been set already or when called from a TLS destructor.
688
+ pub ( crate ) fn set_current ( thread : Thread ) {
689
+ CURRENT . with ( |current| current. set ( thread) . unwrap ( ) ) ;
690
+ }
691
+
692
+ /// Gets a handle to the thread that invokes it.
693
+ ///
694
+ /// In contrast to the public `current` function, this will not panic if called
695
+ /// from inside a TLS destructor.
696
+ pub ( crate ) fn try_current ( ) -> Option < Thread > {
697
+ CURRENT
698
+ . try_with ( |current| current. get_or_init ( || Thread :: new ( imp:: Thread :: get_name ( ) ) ) . clone ( ) )
699
+ . ok ( )
700
+ }
701
+
686
702
/// Gets a handle to the thread that invokes it.
687
703
///
688
704
/// # Examples
@@ -705,7 +721,7 @@ where
705
721
#[ must_use]
706
722
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
707
723
pub fn current ( ) -> Thread {
708
- thread_info :: current_thread ( ) . expect (
724
+ try_current ( ) . expect (
709
725
"use of std::thread::current() is not possible \
710
726
after the thread's local data has been destroyed",
711
727
)
0 commit comments