diff options
| author | bors <bors@rust-lang.org> | 2020-07-14 20:19:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-14 20:19:59 +0000 |
| commit | 23744c84d9c0f8e4e870edb983f1ad6d33449c34 (patch) | |
| tree | 873851698947a162abdd85a971618981b1e19b2a /src/libstd | |
| parent | 2002ebacfbca288830a3c308ddc8189705c608fe (diff) | |
| parent | dbe7ed33cd14166ed52ff02f4db145e199c348cd (diff) | |
Auto merge of #74342 - Manishearth:rollup-l63pesj, r=Manishearth
Rollup of 11 pull requests Successful merges: - #73759 (Add missing Stdin and StdinLock examples) - #74211 (Structured suggestion when not using struct pattern) - #74228 (Provide structured suggestion on unsized fields and fn params) - #74252 (Don't allow `DESTDIR` to influence LLVM builds) - #74263 (Slight reorganization of sys/(fast_)thread_local) - #74271 (process_unix: prefer i32::*_be_bytes over manually shifting bytes) - #74272 (pprust: support multiline comments within lines) - #74332 (Update cargo) - #74334 (bootstrap: Improve wording on docs for `verbose-tests`) - #74336 (typeck: use `item_name` in cross-crate packed diag) - #74340 (lint: use `transparent_newtype_field` to avoid ICE) Failed merges: r? @ghost
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/stdio.rs | 31 | ||||
| -rw-r--r-- | src/libstd/sys/cloudabi/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/thread_local_dtor.rs (renamed from src/libstd/sys/hermit/fast_thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/thread_local_key.rs (renamed from src/libstd/sys/wasm/thread_local.rs) | 10 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/thread_local_key.rs (renamed from src/libstd/sys/sgx/thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/unix/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process/process_unix.rs | 26 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread_local_dtor.rs (renamed from src/libstd/sys/unix/fast_thread_local.rs) | 5 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread_local_key.rs (renamed from src/libstd/sys/unix/thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/vxworks/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/vxworks/thread_local_dtor.rs (renamed from src/libstd/sys/vxworks/fast_thread_local.rs) | 4 | ||||
| -rw-r--r-- | src/libstd/sys/vxworks/thread_local_key.rs (renamed from src/libstd/sys/vxworks/thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/mod.rs | 8 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/thread_local_dtor.rs (renamed from src/libstd/sys/wasm/fast_thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/thread_local_key.rs (renamed from src/libstd/sys/hermit/thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/windows/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/windows/thread_local_dtor.rs (renamed from src/libstd/sys/windows/fast_thread_local.rs) | 2 | ||||
| -rw-r--r-- | src/libstd/sys/windows/thread_local_key.rs (renamed from src/libstd/sys/windows/thread_local.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys_common/mod.rs | 3 | ||||
| -rw-r--r-- | src/libstd/sys_common/thread_local_dtor.rs | 49 | ||||
| -rw-r--r-- | src/libstd/sys_common/thread_local_key.rs (renamed from src/libstd/sys_common/thread_local.rs) | 39 | ||||
| -rw-r--r-- | src/libstd/thread/local.rs | 4 |
25 files changed, 126 insertions, 81 deletions
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index d6b7ad6254a..156f555be02 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -256,9 +256,23 @@ fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> { /// [`BufRead`]: trait.BufRead.html /// /// ### Note: Windows Portability Consideration +/// /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return /// an error. +/// +/// # Examples +/// +/// ```no_run +/// use std::io::{self, Read}; +/// +/// fn main() -> io::Result<()> { +/// let mut buffer = String::new(); +/// let mut stdin = io::stdin(); // We get `Stdin` here. +/// stdin.read_to_string(&mut buffer)?; +/// Ok(()) +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdin { inner: Arc<Mutex<BufReader<Maybe<StdinRaw>>>>, @@ -274,9 +288,26 @@ pub struct Stdin { /// [`Stdin::lock`]: struct.Stdin.html#method.lock /// /// ### Note: Windows Portability Consideration +/// /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return /// an error. +/// +/// # Examples +/// +/// ```no_run +/// use std::io::{self, Read}; +/// +/// fn main() -> io::Result<()> { +/// let mut buffer = String::new(); +/// let stdin = io::stdin(); // We get `Stdin` here. +/// { +/// let mut stdin_lock = stdin.lock(); // We get `StdinLock` here. +/// stdin_lock.read_to_string(&mut buffer)?; +/// } // `StdinLock` is dropped here. +/// Ok(()) +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct StdinLock<'a> { inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>, diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index 8dbc31472d6..f7dd2c8d00f 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -16,8 +16,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -#[path = "../unix/thread_local.rs"] -pub mod thread_local; +#[path = "../unix/thread_local_key.rs"] +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs index 7bdc1be3b17..675b82ceb77 100644 --- a/src/libstd/sys/hermit/mod.rs +++ b/src/libstd/sys/hermit/mod.rs @@ -22,7 +22,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -37,7 +36,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; use crate::io::ErrorKind; diff --git a/src/libstd/sys/hermit/fast_thread_local.rs b/src/libstd/sys/hermit/thread_local_dtor.rs index 9b683fce157..9b683fce157 100644 --- a/src/libstd/sys/hermit/fast_thread_local.rs +++ b/src/libstd/sys/hermit/thread_local_dtor.rs diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/hermit/thread_local_key.rs index f8be9863ed5..bf1b49eb83b 100644 --- a/src/libstd/sys/wasm/thread_local.rs +++ b/src/libstd/sys/hermit/thread_local_key.rs @@ -2,25 +2,25 @@ pub type Key = usize; #[inline] pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn destroy(_key: Key) { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub fn requires_synchronized_create() -> bool { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index 397dd496ae8..a4968ff7d4f 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -30,7 +30,7 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/sgx/thread_local.rs b/src/libstd/sys/sgx/thread_local_key.rs index b21784475f0..b21784475f0 100644 --- a/src/libstd/sys/sgx/thread_local.rs +++ b/src/libstd/sys/sgx/thread_local_key.rs diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b1688e74173..eddf00d3979 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -47,7 +47,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -68,7 +67,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index f389c60615f..de35fe0521d 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -1,3 +1,4 @@ +use crate::convert::TryInto; use crate::fmt; use crate::io::{self, Error, ErrorKind}; use crate::ptr; @@ -17,7 +18,7 @@ impl Command { default: Stdio, needs_stdin: bool, ) -> io::Result<(Process, StdioPipes)> { - const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX"; + const CLOEXEC_MSG_FOOTER: [u8; 4] = *b"NOEX"; let envp = self.capture_env(); @@ -52,11 +53,12 @@ impl Command { drop(input); let Err(err) = self.do_exec(theirs, envp.as_ref()); let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; + let errno = errno.to_be_bytes(); let bytes = [ - (errno >> 24) as u8, - (errno >> 16) as u8, - (errno >> 8) as u8, - (errno >> 0) as u8, + errno[0], + errno[1], + errno[2], + errno[3], CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1], CLOEXEC_MSG_FOOTER[2], @@ -81,12 +83,13 @@ impl Command { match input.read(&mut bytes) { Ok(0) => return Ok((p, ours)), Ok(8) => { + let (errno, footer) = bytes.split_at(4); assert!( - combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4..8]), + combine(CLOEXEC_MSG_FOOTER) == combine(footer.try_into().unwrap()), "Validation on the CLOEXEC pipe failed: {:?}", bytes ); - let errno = combine(&bytes[0..4]); + let errno = combine(errno.try_into().unwrap()); assert!(p.wait().is_ok(), "wait() should either return Ok or panic"); return Err(Error::from_raw_os_error(errno)); } @@ -103,13 +106,8 @@ impl Command { } } - fn combine(arr: &[u8]) -> i32 { - let a = arr[0] as u32; - let b = arr[1] as u32; - let c = arr[2] as u32; - let d = arr[3] as u32; - - ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32 + fn combine(arr: [u8; 4]) -> i32 { + i32::from_be_bytes(arr) } } diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/thread_local_dtor.rs index 8730b4de8be..c3275eb6f0e 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/thread_local_dtor.rs @@ -1,6 +1,9 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] +//! Provides thread-local destructors without an associated "key", which +//! can be more efficient. + // Since what appears to be glibc 2.18 this symbol has been shipped which // GCC and clang both use to invoke destructors in thread_local globals, so // let's do the same! @@ -16,7 +19,7 @@ ))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::mem; - use crate::sys_common::thread_local::register_dtor_fallback; + use crate::sys_common::thread_local_dtor::register_dtor_fallback; extern "C" { #[linkage = "extern_weak"] diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local_key.rs index 2c5b94b1e61..2c5b94b1e61 100644 --- a/src/libstd/sys/unix/thread_local.rs +++ b/src/libstd/sys/unix/thread_local_key.rs diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs index 0787e709898..1132a849e2f 100644 --- a/src/libstd/sys/vxworks/mod.rs +++ b/src/libstd/sys/vxworks/mod.rs @@ -13,7 +13,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -29,7 +28,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/thread_local_dtor.rs index 098668cf521..3f73f6c4903 100644 --- a/src/libstd/sys/vxworks/fast_thread_local.rs +++ b/src/libstd/sys/vxworks/thread_local_dtor.rs @@ -5,7 +5,3 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::sys_common::thread_local::register_dtor_fallback; register_dtor_fallback(t, dtor); } - -pub fn requires_move_before_drop() -> bool { - false -} diff --git a/src/libstd/sys/vxworks/thread_local.rs b/src/libstd/sys/vxworks/thread_local_key.rs index 2c5b94b1e61..2c5b94b1e61 100644 --- a/src/libstd/sys/vxworks/thread_local.rs +++ b/src/libstd/sys/vxworks/thread_local_key.rs diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 4fe9661421b..85f5282034f 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -36,8 +36,6 @@ pub mod net; pub mod os; pub use crate::sys_common::os_str_bytes as os_str; pub mod ext; -#[path = "../wasm/fast_thread_local.rs"] -pub mod fast_thread_local; pub mod path; pub mod pipe; pub mod process; @@ -47,8 +45,10 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -#[path = "../wasm/thread_local.rs"] -pub mod thread_local; +#[path = "../wasm/thread_local_dtor.rs"] +pub mod thread_local_dtor; +#[path = "../wasm/thread_local_key.rs"] +pub mod thread_local_key; pub mod time; #[cfg(not(test))] diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 050e8099af4..6939596e52d 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -20,7 +20,6 @@ pub mod alloc; pub mod args; pub mod cmath; pub mod env; -pub mod fast_thread_local; pub mod fs; pub mod io; pub mod memchr; @@ -32,7 +31,8 @@ pub mod process; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/thread_local_dtor.rs index 85d66098302..85d66098302 100644 --- a/src/libstd/sys/wasm/fast_thread_local.rs +++ b/src/libstd/sys/wasm/thread_local_dtor.rs diff --git a/src/libstd/sys/hermit/thread_local.rs b/src/libstd/sys/wasm/thread_local_key.rs index f8be9863ed5..f8be9863ed5 100644 --- a/src/libstd/sys/hermit/thread_local.rs +++ b/src/libstd/sys/wasm/thread_local_key.rs diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 193ab5b47ef..9a52371280e 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -20,7 +20,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fs; pub mod handle; pub mod io; @@ -35,7 +34,8 @@ pub mod process; pub mod rand; pub mod rwlock; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; cfg_if::cfg_if! { if #[cfg(not(target_vendor = "uwp"))] { diff --git a/src/libstd/sys/windows/fast_thread_local.rs b/src/libstd/sys/windows/thread_local_dtor.rs index 191fa07f32a..7be13bc4b2b 100644 --- a/src/libstd/sys/windows/fast_thread_local.rs +++ b/src/libstd/sys/windows/thread_local_dtor.rs @@ -1,4 +1,4 @@ #![unstable(feature = "thread_local_internals", issue = "none")] #![cfg(target_thread_local)] -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; +pub use crate::sys_common::thread_local_dtor::register_dtor_fallback as register_dtor; diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local_key.rs index e0bb102b3af..e0bb102b3af 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local_key.rs 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}; diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 094c468a677..ecd6fbc6b93 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -363,7 +363,7 @@ pub mod fast { use crate::cell::Cell; use crate::fmt; use crate::mem; - use crate::sys::fast_thread_local::register_dtor; + use crate::sys::thread_local_dtor::register_dtor; #[derive(Copy, Clone)] enum DtorState { @@ -468,7 +468,7 @@ pub mod os { use crate::fmt; use crate::marker; use crate::ptr; - use crate::sys_common::thread_local::StaticKey as OsStaticKey; + use crate::sys_common::thread_local_key::StaticKey as OsStaticKey; pub struct Key<T> { // OS-TLS key that we'll use to key off. |
