@@ -16,14 +16,15 @@ static HAS_DTORS: AtomicBool = AtomicBool::new(false);
16
16
// Using a per-thread list avoids the problems in synchronizing global state.
17
17
#[ thread_local]
18
18
#[ cfg( target_thread_local) ]
19
- static mut DESTRUCTORS : Vec < ( * mut u8 , unsafe extern "C" fn ( * mut u8 ) ) > = Vec :: new ( ) ;
19
+ static DESTRUCTORS : crate :: cell:: RefCell < Vec < ( * mut u8 , unsafe extern "C" fn ( * mut u8 ) ) > > =
20
+ crate :: cell:: RefCell :: new ( Vec :: new ( ) ) ;
20
21
21
22
// Ensure this can never be inlined because otherwise this may break in dylibs.
22
23
// See #44391.
23
24
#[ inline( never) ]
24
25
#[ cfg( target_thread_local) ]
25
26
pub unsafe fn register_keyless_dtor ( t : * mut u8 , dtor : unsafe extern "C" fn ( * mut u8 ) ) {
26
- DESTRUCTORS . push ( ( t, dtor) ) ;
27
+ DESTRUCTORS . try_borrow_mut ( ) . expect ( "global allocator may not TLS storage" ) . push ( ( t, dtor) ) ;
27
28
HAS_DTORS . store ( true , Relaxed ) ;
28
29
}
29
30
@@ -37,11 +38,11 @@ unsafe fn run_keyless_dtors() {
37
38
// the case that this loop always terminates because we provide the
38
39
// guarantee that a TLS key cannot be set after it is flagged for
39
40
// destruction.
40
- while let Some ( ( ptr, dtor) ) = DESTRUCTORS . pop ( ) {
41
+ while let Some ( ( ptr, dtor) ) = DESTRUCTORS . borrow_mut ( ) . pop ( ) {
41
42
( dtor) ( ptr) ;
42
43
}
43
44
// We're done so free the memory.
44
- DESTRUCTORS = Vec :: new ( ) ;
45
+ DESTRUCTORS . replace ( Vec :: new ( ) ) ;
45
46
}
46
47
47
48
type Key = c:: DWORD ;
0 commit comments