File tree Expand file tree Collapse file tree 1 file changed +23
-11
lines changed
library/std/src/sys/thread_local/destructors Expand file tree Collapse file tree 1 file changed +23
-11
lines changed Original file line number Diff line number Diff line change 1- use crate :: cell:: RefCell ;
1+ use crate :: cell:: { Cell , RefCell } ;
22use crate :: sys:: thread_local:: guard;
33
4+ #[ thread_local]
5+ static REENTRANT_DTOR : Cell < Option < ( * mut u8 , unsafe extern "C" fn ( * mut u8 ) ) > > = Cell :: new ( None ) ;
6+
47#[ thread_local]
58static DTORS : RefCell < Vec < ( * mut u8 , unsafe extern "C" fn ( * mut u8 ) ) > > = RefCell :: new ( Vec :: new ( ) ) ;
69
710pub unsafe fn register ( t : * mut u8 , dtor : unsafe extern "C" fn ( * mut u8 ) ) {
8- let Ok ( mut dtors) = DTORS . try_borrow_mut ( ) else {
9- // This point can only be reached if the global allocator calls this
10- // function again.
11- // FIXME: maybe use the system allocator instead?
12- rtabort ! ( "the global allocator may not use TLS with destructors" ) ;
13- } ;
14-
15- guard:: enable ( ) ;
16-
17- dtors. push ( ( t, dtor) ) ;
11+ // Borrow DTORS can only fail if the global allocator calls this
12+ // function again.
13+ if let Ok ( mut dtors) = DTORS . try_borrow_mut ( ) {
14+ guard:: enable ( ) ;
15+ dtors. push ( ( t, dtor) ) ;
16+ } else if REENTRANT_DTOR . get ( ) . is_none ( ) {
17+ guard:: enable ( ) ;
18+ REENTRANT_DTOR . set ( Some ( ( t, dtor) ) ) ;
19+ } else {
20+ rtabort ! (
21+ "the global allocator may only create one thread-local variable with a destructor"
22+ ) ;
23+ }
1824}
1925
2026/// The [`guard`] module contains platform-specific functions which will run this
@@ -41,4 +47,10 @@ pub unsafe fn run() {
4147 }
4248 }
4349 }
50+
51+ if let Some ( ( t, dtor) ) = REENTRANT_DTOR . replace ( None ) {
52+ unsafe {
53+ dtor ( t) ;
54+ }
55+ }
4456}
You can’t perform that action at this time.
0 commit comments