summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/hermit/thread_local_dtor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/hermit/thread_local_dtor.rs')
-rw-r--r--library/std/src/sys/hermit/thread_local_dtor.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs
new file mode 100644
index 000000000..9b683fce1
--- /dev/null
+++ b/library/std/src/sys/hermit/thread_local_dtor.rs
@@ -0,0 +1,36 @@
+#![cfg(target_thread_local)]
+#![unstable(feature = "thread_local_internals", issue = "none")]
+
+// Simplify dtor registration by using a list of destructors.
+// The this solution works like the implementation of macOS and
+// doesn't additional OS support
+
+use crate::cell::Cell;
+use crate::ptr;
+
+#[thread_local]
+static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut());
+
+type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
+
+pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
+ if DTORS.get().is_null() {
+ let v: Box<List> = box Vec::new();
+ DTORS.set(Box::into_raw(v));
+ }
+
+ let list: &mut List = &mut *DTORS.get();
+ list.push((t, dtor));
+}
+
+// every thread call this function to run through all possible destructors
+pub unsafe fn run_dtors() {
+ let mut ptr = DTORS.replace(ptr::null_mut());
+ while !ptr.is_null() {
+ let list = Box::from_raw(ptr);
+ for (ptr, dtor) in list.into_iter() {
+ dtor(ptr);
+ }
+ ptr = DTORS.replace(ptr::null_mut());
+ }
+}