|
5 | 5 |
|
6 | 6 | use super::{abi, itron::task};
|
7 | 7 | use crate::cell::Cell;
|
8 |
| -use crate::ptr; |
| 8 | +use crate::mem; |
9 | 9 |
|
10 | 10 | #[thread_local]
|
11 |
| -static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut()); |
| 11 | +static REGISTERED: Cell<bool> = Cell::new(false); |
12 | 12 |
|
13 |
| -type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; |
| 13 | +#[thread_local] |
| 14 | +static mut DTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new(); |
14 | 15 |
|
15 | 16 | pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
16 |
| - if DTORS.get().is_null() { |
| 17 | + if !REGISTERED.get() { |
17 | 18 | let tid = task::current_task_id_aborting();
|
18 |
| - let v: Box<List> = box Vec::new(); |
19 |
| - DTORS.set(Box::into_raw(v)); |
20 |
| - |
21 | 19 | // Register `tls_dtor` to make sure the TLS destructors are called
|
22 | 20 | // for tasks created by other means than `std::thread`
|
23 | 21 | unsafe { abi::SOLID_TLS_AddDestructor(tid as i32, tls_dtor) };
|
| 22 | + REGISTERED.set(true); |
24 | 23 | }
|
25 | 24 |
|
26 |
| - let list: &mut List = unsafe { &mut *DTORS.get() }; |
| 25 | + let list = unsafe { &mut DTORS }; |
27 | 26 | list.push((t, dtor));
|
28 | 27 | }
|
29 | 28 |
|
30 | 29 | pub unsafe fn run_dtors() {
|
31 |
| - let ptr = DTORS.get(); |
32 |
| - if !ptr.is_null() { |
33 |
| - // Swap the destructor list, call all registered destructors, |
34 |
| - // and repeat this until the list becomes permanently empty. |
35 |
| - while let Some(list) = Some(crate::mem::replace(unsafe { &mut *ptr }, Vec::new())) |
36 |
| - .filter(|list| !list.is_empty()) |
37 |
| - { |
38 |
| - for (ptr, dtor) in list.into_iter() { |
39 |
| - unsafe { dtor(ptr) }; |
40 |
| - } |
| 30 | + let mut list = mem::take(unsafe { &mut DTORS }); |
| 31 | + while !list.is_empty() { |
| 32 | + for (ptr, dtor) in list { |
| 33 | + unsafe { dtor(ptr) }; |
41 | 34 | }
|
42 | 35 |
|
43 |
| - // Drop the destructor list |
44 |
| - unsafe { Box::from_raw(DTORS.replace(ptr::null_mut())) }; |
| 36 | + list = mem::take(unsafe { &mut DTORS }); |
45 | 37 | }
|
46 | 38 | }
|
47 | 39 |
|
|
0 commit comments