about summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/mod.rs3
-rw-r--r--src/libstd/sys_common/thread_local_dtor.rs49
-rw-r--r--src/libstd/sys_common/thread_local_key.rs (renamed from src/libstd/sys_common/thread_local.rs)39
3 files changed, 54 insertions, 37 deletions
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index e03e0fc8345..e57bb267cbd 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -65,7 +65,8 @@ pub mod remutex;
 pub mod rwlock;
 pub mod thread;
 pub mod thread_info;
-pub mod thread_local;
+pub mod thread_local_dtor;
+pub mod thread_local_key;
 pub mod util;
 pub mod wtf8;
 
diff --git a/src/libstd/sys_common/thread_local_dtor.rs b/src/libstd/sys_common/thread_local_dtor.rs
new file mode 100644
index 00000000000..6f5ebf4a271
--- /dev/null
+++ b/src/libstd/sys_common/thread_local_dtor.rs
@@ -0,0 +1,49 @@
+//! Thread-local destructor
+//!
+//! Besides thread-local "keys" (pointer-sized non-adressable thread-local store
+//! with an associated destructor), many platforms also provide thread-local
+//! destructors that are not associated with any particular data. These are
+//! often more efficient.
+//!
+//! This module provides a fallback implementation for that interface, based
+//! on the less efficient thread-local "keys". Each platform provides
+//! a `thread_local_dtor` module which will either re-export the fallback,
+//! or implement something more efficient.
+
+#![unstable(feature = "thread_local_internals", issue = "none")]
+#![allow(dead_code)] // sys isn't exported yet
+
+use crate::ptr;
+use crate::sys_common::thread_local_key::StaticKey;
+
+pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
+    // The fallback implementation uses a vanilla OS-based TLS key to track
+    // the list of destructors that need to be run for this thread. The key
+    // then has its own destructor which runs all the other destructors.
+    //
+    // The destructor for DTORS is a little special in that it has a `while`
+    // loop to continuously drain the list of registered destructors. It
+    // *should* be the case that this loop always terminates because we
+    // provide the guarantee that a TLS key cannot be set after it is
+    // flagged for destruction.
+
+    static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
+    type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
+    if DTORS.get().is_null() {
+        let v: Box<List> = box Vec::new();
+        DTORS.set(Box::into_raw(v) as *mut u8);
+    }
+    let list: &mut List = &mut *(DTORS.get() as *mut List);
+    list.push((t, dtor));
+
+    unsafe extern "C" fn run_dtors(mut ptr: *mut u8) {
+        while !ptr.is_null() {
+            let list: Box<List> = Box::from_raw(ptr as *mut List);
+            for (ptr, dtor) in list.into_iter() {
+                dtor(ptr);
+            }
+            ptr = DTORS.get();
+            DTORS.set(ptr::null_mut());
+        }
+    }
+}
diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local_key.rs
index 756b8d044a2..ac5b128298d 100644
--- a/src/libstd/sys_common/thread_local.rs
+++ b/src/libstd/sys_common/thread_local_key.rs
@@ -4,7 +4,7 @@
 //! using the native OS-provided facilities (think `TlsAlloc` or
 //! `pthread_setspecific`). The interface of this differs from the other types
 //! of thread-local-storage provided in this crate in that OS-based TLS can only
-//! get/set pointers,
+//! get/set pointer-sized data, possibly with an associated destructor.
 //!
 //! This module also provides two flavors of TLS. One is intended for static
 //! initialization, and does not contain a `Drop` implementation to deallocate
@@ -14,7 +14,7 @@
 //! # Usage
 //!
 //! This module should likely not be used directly unless other primitives are
-//! being built on. types such as `thread_local::spawn::Key` are likely much
+//! being built on. Types such as `thread_local::spawn::Key` are likely much
 //! more useful in practice than this OS-based version which likely requires
 //! unsafe code to interoperate with.
 //!
@@ -48,9 +48,8 @@
 #![unstable(feature = "thread_local_internals", issue = "none")]
 #![allow(dead_code)] // sys isn't exported yet
 
-use crate::ptr;
 use crate::sync::atomic::{self, AtomicUsize, Ordering};
-use crate::sys::thread_local as imp;
+use crate::sys::thread_local_key as imp;
 use crate::sys_common::mutex::Mutex;
 
 /// A type for TLS keys that are statically allocated.
@@ -233,38 +232,6 @@ impl Drop for Key {
     }
 }
 
-pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
-    // The fallback implementation uses a vanilla OS-based TLS key to track
-    // the list of destructors that need to be run for this thread. The key
-    // then has its own destructor which runs all the other destructors.
-    //
-    // The destructor for DTORS is a little special in that it has a `while`
-    // loop to continuously drain the list of registered destructors. It
-    // *should* be the case that this loop always terminates because we
-    // provide the guarantee that a TLS key cannot be set after it is
-    // flagged for destruction.
-
-    static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
-    type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
-    if DTORS.get().is_null() {
-        let v: Box<List> = box Vec::new();
-        DTORS.set(Box::into_raw(v) as *mut u8);
-    }
-    let list: &mut List = &mut *(DTORS.get() as *mut List);
-    list.push((t, dtor));
-
-    unsafe extern "C" fn run_dtors(mut ptr: *mut u8) {
-        while !ptr.is_null() {
-            let list: Box<List> = Box::from_raw(ptr as *mut List);
-            for (ptr, dtor) in list.into_iter() {
-                dtor(ptr);
-            }
-            ptr = DTORS.get();
-            DTORS.set(ptr::null_mut());
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::{Key, StaticKey};