xref: /relibc/ralloc/shim/src/thread_destructor.rs (revision 92ca1d73ef9a68d6508c46e2f6ad99fc65e8bc68)
1 //! Thread destructors.
2 //!
3 //! This module supplies the ability to register destructors called upon thread exit.
4 
5 pub use self::arch::*;
6 
7 /// Thread destructors for Linux/BSD.
8 #[cfg(not(target_os = "macos"))]
9 pub mod arch {
10     extern {
11         #[linkage = "extern_weak"]
12         static __dso_handle: *mut u8;
13         #[linkage = "extern_weak"]
14         static __cxa_thread_atexit_impl: *const u8;
15     }
16 
17     /// Register a thread destructor.
18     // TODO: Due to rust-lang/rust#18804, make sure this is not generic!
19     pub fn register(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
20         use core::mem;
21 
22         /// A thread destructor.
23         type Dtor = unsafe extern fn(dtor: unsafe extern fn(*mut u8), arg: *mut u8, dso_handle: *mut u8) -> i32;
24 
25         unsafe {
26             // Make sure the symbols exist.
27             assert!(!__cxa_thread_atexit_impl.is_null());
28 
29             mem::transmute::<*const u8, Dtor>(__cxa_thread_atexit_impl)
30                 (dtor, t, &__dso_handle as *const _ as *mut _)
31         };
32     }
33 }
34 
35 /// Thread destructors for Mac OS.
36 #[cfg(target_os = "macos")]
37 pub mod arch {
38     extern {
39         fn _tlv_atexit(dtor: unsafe extern fn(*mut u8), arg: *mut u8);
40     }
41 
42     /// Register a thread destructor.
43     pub fn register(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
44         _tlv_atexit(dtor, t);
45     }
46 }
47