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