3
3
4
4
#![ unstable( feature = "thread_local_internals" , issue = "none" ) ]
5
5
#![ cfg( target_thread_local) ]
6
- use super :: c;
7
6
8
7
// Using a per-thread list avoids the problems in synchronizing global state.
9
8
#[ thread_local]
@@ -13,27 +12,17 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
13
12
DESTRUCTORS . push ( ( t, dtor) ) ;
14
13
}
15
14
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) ;
38
25
}
26
+ // We're done so free the memory.
27
+ DESTRUCTORS = Vec :: new ( ) ;
39
28
}
0 commit comments