Skip to content

Commit 1048651

Browse files
committed
Run destructors from existing tls callback
1 parent 9212f40 commit 1048651

File tree

2 files changed

+14
-23
lines changed

2 files changed

+14
-23
lines changed

library/std/src/sys/windows/thread_local_dtor.rs

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
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
}

library/std/src/sys/windows/thread_local_key.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::
196196
unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID) {
197197
if dwReason == c::DLL_THREAD_DETACH || dwReason == c::DLL_PROCESS_DETACH {
198198
run_dtors();
199+
#[cfg(target_thread_local)]
200+
super::thread_local_dtor::run_keyless_dtors();
199201
}
200202

201203
// See comments above for what this is doing. Note that we don't need this

0 commit comments

Comments
 (0)