]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/solid/thread_local_dtor.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / library / std / src / sys / solid / thread_local_dtor.rs
1 #![cfg(target_thread_local)]
2 #![unstable(feature = "thread_local_internals", issue = "none")]
3
4 // Simplify dtor registration by using a list of destructors.
5
6 use super::{abi, itron::task};
7 use crate::cell::Cell;
8 use crate::mem;
9
10 #[thread_local]
11 static REGISTERED: Cell<bool> = Cell::new(false);
12
13 #[thread_local]
14 static mut DTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new();
15
16 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
17     if !REGISTERED.get() {
18         let tid = task::current_task_id_aborting();
19         // Register `tls_dtor` to make sure the TLS destructors are called
20         // for tasks created by other means than `std::thread`
21         unsafe { abi::SOLID_TLS_AddDestructor(tid as i32, tls_dtor) };
22         REGISTERED.set(true);
23     }
24
25     let list = unsafe { &mut DTORS };
26     list.push((t, dtor));
27 }
28
29 pub unsafe fn run_dtors() {
30     let mut list = mem::take(unsafe { &mut DTORS });
31     while !list.is_empty() {
32         for (ptr, dtor) in list {
33             unsafe { dtor(ptr) };
34         }
35
36         list = mem::take(unsafe { &mut DTORS });
37     }
38 }
39
40 unsafe extern "C" fn tls_dtor(_unused: *mut u8) {
41     unsafe { run_dtors() };
42 }