std/sys/thread_local/destructors/
list.rs

1use crate::alloc::System;
2use crate::cell::RefCell;
3use crate::sys::thread_local::guard;
4
5#[thread_local]
6static DTORS: RefCell<Vec<(*mut u8, unsafe extern "C" fn(*mut u8)), System>> =
7    RefCell::new(Vec::new_in(System));
8
9pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
10    let Ok(mut dtors) = DTORS.try_borrow_mut() else {
11        rtabort!("the System allocator may not use TLS with destructors")
12    };
13    guard::enable();
14    dtors.push((t, dtor));
15}
16
17/// The [`guard`] module contains platform-specific functions which will run this
18/// function on thread exit if [`guard::enable`] has been called.
19///
20/// # Safety
21///
22/// May only be run on thread exit to guarantee that there are no live references
23/// to TLS variables while they are destroyed.
24pub unsafe fn run() {
25    loop {
26        let mut dtors = DTORS.borrow_mut();
27        match dtors.pop() {
28            Some((t, dtor)) => {
29                drop(dtors);
30                unsafe {
31                    dtor(t);
32                }
33            }
34            None => {
35                // Free the list memory.
36                *dtors = Vec::new_in(System);
37                break;
38            }
39        }
40    }
41}