thread_destructor.rs 1.3 KB

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