@@ -64,7 +64,7 @@ impl LazyKey {
6464 } ;
6565 rtassert ! ( key as usize != KEY_SENTVAL ) ;
6666
67- let final_key = match self . key . compare_exchange (
67+ match self . key . compare_exchange (
6868 KEY_SENTVAL ,
6969 key as usize ,
7070 Ordering :: Release ,
@@ -77,15 +77,18 @@ impl LazyKey {
7777 super :: destroy ( key) ;
7878 n
7979 } ,
80- } ;
80+ }
81+ }
8182
82- // TODO: This must be called for every thread that uses this LazyKey once!
83- #[ cfg( not( target_thread_local) ) ]
84- if self . dtor . is_some ( ) {
85- unsafe { register_dtor ( self ) } ;
83+ /// Registers destructor to run at process exit.
84+ #[ cfg( not( target_thread_local) ) ]
85+ pub fn register_process_dtor ( & ' static self ) {
86+ if self . dtor . is_none ( ) {
87+ return ;
8688 }
8789
88- final_key
90+ crate :: sys:: thread_local:: guard:: enable ( ) ;
91+ lazy_keys ( ) . borrow_mut ( ) . push ( self ) ;
8992 }
9093}
9194
@@ -131,42 +134,31 @@ fn lazy_keys() -> &'static crate::cell::RefCell<Vec<&'static LazyKey>> {
131134 unsafe { & * ptr }
132135}
133136
134- /// Registers destructor to run at process exit.
135- #[ cfg( not( target_thread_local) ) ]
136- unsafe fn register_dtor ( lazy_key : & ' static LazyKey ) {
137- crate :: sys:: thread_local:: guard:: enable ( ) ;
138-
139- lazy_keys ( ) . borrow_mut ( ) . push ( lazy_key) ;
140- }
141-
142137/// Run destructors at process exit.
143138///
144139/// SAFETY: This will and must only be run by the destructor callback in [`guard`].
145140#[ cfg( not( target_thread_local) ) ]
146141pub unsafe fn run_dtors ( ) {
147142 let lazy_keys_cell = lazy_keys ( ) ;
148- let mut lazy_keys = lazy_keys_cell. take ( ) ;
149143
150144 for _ in 0 ..5 {
151145 let mut any_run = false ;
152- for lazy_key in & lazy_keys {
153- if let Some ( dtor) = & lazy_key. dtor {
154- let key = lazy_key. force ( ) ;
155- let ptr = unsafe { super :: get ( key) } ;
156- if !ptr. is_null ( ) {
157- unsafe { dtor ( ptr) } ;
158- unsafe { super :: set ( key, crate :: ptr:: null_mut ( ) ) } ;
159- any_run = true ;
146+
147+ for lazy_key in lazy_keys_cell. take ( ) {
148+ let key = lazy_key. force ( ) ;
149+ let ptr = unsafe { super :: get ( key) } ;
150+ if !ptr. is_null ( ) {
151+ // SAFETY: only keys with destructors are registered.
152+ unsafe {
153+ let Some ( dtor) = & lazy_key. dtor else { crate :: hint:: unreachable_unchecked ( ) } ;
154+ dtor ( ptr) ;
160155 }
156+ any_run = true ;
161157 }
162158 }
163159
164- let mut new_lazy_keys = lazy_keys_cell. borrow_mut ( ) ;
165-
166- if !any_run && new_lazy_keys. is_empty ( ) {
160+ if !any_run {
167161 break ;
168162 }
169-
170- lazy_keys. extend ( new_lazy_keys. drain ( ..) ) ;
171163 }
172164}
0 commit comments