33
44#![ unstable( feature = "thread_local_internals" , issue = "none" ) ]
55#![ cfg( target_thread_local) ]
6- use super :: c;
76
87// Using a per-thread list avoids the problems in synchronizing global state.
98#[ thread_local]
@@ -13,27 +12,17 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
1312 DESTRUCTORS . push ( ( t, dtor) ) ;
1413}
1514
16- // See windows/thread_local_keys.rs for an explanation of this callback function.
17- // The short version is that all the function pointers in the `.CRT$XL*` array
18- // will be called whenever a thread or process starts or ends.
19-
20- #[ link_section = ".CRT$XLD" ]
21- #[ doc( hidden) ]
22- #[ used]
23- pub static TLS_CALLBACK : unsafe extern "system" fn ( c:: LPVOID , c:: DWORD , c:: LPVOID ) = tls_callback;
24-
25- unsafe extern "system" fn tls_callback ( _: c:: LPVOID , reason : c:: DWORD , _: c:: LPVOID ) {
26- if reason == c:: DLL_THREAD_DETACH || reason == c:: DLL_PROCESS_DETACH {
27- // Drop all the destructors.
28- //
29- // Note: While this is potentially an infinite loop, it *should* be
30- // the case that this loop always terminates because we provide the
31- // guarantee that a TLS key cannot be set after it is flagged for
32- // destruction.
33- while let Some ( ( ptr, dtor) ) = DESTRUCTORS . pop ( ) {
34- ( dtor) ( ptr) ;
35- }
36- // We're done so free the memory.
37- DESTRUCTORS . shrink_to_fit ( ) ;
15+ /// Runs destructors. This should not be called until thread exit.
16+ pub unsafe fn run_keyless_dtors ( ) {
17+ // Drop all the destructors.
18+ //
19+ // Note: While this is potentially an infinite loop, it *should* be
20+ // the case that this loop always terminates because we provide the
21+ // guarantee that a TLS key cannot be set after it is flagged for
22+ // destruction.
23+ while let Some ( ( ptr, dtor) ) = DESTRUCTORS . pop ( ) {
24+ ( dtor) ( ptr) ;
3825 }
26+ // We're done so free the memory.
27+ DESTRUCTORS = Vec :: new ( ) ;
3928}
0 commit comments