X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibstd%2Fthread%2Flocal.rs;h=7a9b642350fa62c10ae7f9174125baf53a07e691;hb=6f4ab9458a7ad06c8ce630604f533c8c0c0acef4;hp=be433e2b81e6b6758ea886803254488d88484718;hpb=6270257f4ef6e65213631d6b5a2a85807b8b2364;p=rust.git diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index be433e2b81e..7a9b642350f 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -91,13 +91,13 @@ pub struct LocalKey { // // Note that the thunk is itself unsafe because the returned lifetime of the // slot where data lives, `'static`, is not actually valid. The lifetime - // here is actually `'thread`! + // here is actually slightly shorter than the currently running thread! // // Although this is an extra layer of indirection, it should in theory be // trivially devirtualizable by LLVM because the value of `inner` never // changes and the constant should be readonly within a crate. This mainly // only runs into problems when TLS statics are exported across crates. - inner: fn() -> Option<&'static UnsafeCell>>, + inner: unsafe fn() -> Option<&'static UnsafeCell>>, // initialization routine to invoke to create a value init: fn() -> T, @@ -110,7 +110,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -#[cfg(not(stage0))] /// Declare a new thread local storage key of type [`std::thread::LocalKey`]. /// /// # Syntax @@ -152,19 +151,19 @@ macro_rules! thread_local { ); } -#[cfg(not(stage0))] #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary", issue = "0")] #[macro_export] #[allow_internal_unstable] +#[cfg_attr(not(stage0), allow_internal_unsafe)] macro_rules! __thread_local_inner { ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => { $(#[$attr])* $vis static $name: $crate::thread::LocalKey<$t> = { fn __init() -> $t { $init } - fn __getit() -> $crate::option::Option< + unsafe fn __getit() -> $crate::option::Option< &'static $crate::cell::UnsafeCell< $crate::option::Option<$t>>> { @@ -180,76 +179,13 @@ fn __getit() -> $crate::option::Option< __KEY.get() } - $crate::thread::LocalKey::new(__getit, __init) + unsafe { + $crate::thread::LocalKey::new(__getit, __init) + } }; } } -#[cfg(stage0)] -/// Declare a new thread local storage key of type `std::thread::LocalKey`. -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -#[allow_internal_unstable] -macro_rules! thread_local { - // rule 0: empty (base case for the recursion) - () => {}; - - // rule 1: process multiple declarations where the first one is private - ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => ( - thread_local!($(#[$attr])* static $name: $t = $init); // go to rule 2 - thread_local!($($rest)*); - ); - - // rule 2: handle a single private declaration - ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr) => ( - $(#[$attr])* static $name: $crate::thread::LocalKey<$t> = - __thread_local_inner!($t, $init); - ); - - // rule 3: handle multiple declarations where the first one is public - ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => ( - thread_local!($(#[$attr])* pub static $name: $t = $init); // go to rule 4 - thread_local!($($rest)*); - ); - - // rule 4: handle a single public declaration - ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr) => ( - $(#[$attr])* pub static $name: $crate::thread::LocalKey<$t> = - __thread_local_inner!($t, $init); - ); -} - -#[cfg(stage0)] -#[doc(hidden)] -#[unstable(feature = "thread_local_internals", - reason = "should not be necessary", - issue = "0")] -#[macro_export] -#[allow_internal_unstable] -macro_rules! __thread_local_inner { - ($t:ty, $init:expr) => {{ - fn __init() -> $t { $init } - - fn __getit() -> $crate::option::Option< - &'static $crate::cell::UnsafeCell< - $crate::option::Option<$t>>> - { - #[thread_local] - #[cfg(target_thread_local)] - static __KEY: $crate::thread::__FastLocalKeyInner<$t> = - $crate::thread::__FastLocalKeyInner::new(); - - #[cfg(not(target_thread_local))] - static __KEY: $crate::thread::__OsLocalKeyInner<$t> = - $crate::thread::__OsLocalKeyInner::new(); - - __KEY.get() - } - - $crate::thread::LocalKey::new(__getit, __init) - }} -} - /// Indicator of the state of a thread local storage key. #[unstable(feature = "thread_local_state", reason = "state querying was recently added", @@ -319,11 +255,11 @@ impl LocalKey { #[unstable(feature = "thread_local_internals", reason = "recently added to create a key", issue = "0")] - pub const fn new(inner: fn() -> Option<&'static UnsafeCell>>, - init: fn() -> T) -> LocalKey { + pub const unsafe fn new(inner: unsafe fn() -> Option<&'static UnsafeCell>>, + init: fn() -> T) -> LocalKey { LocalKey { - inner: inner, - init: init, + inner, + init, } } @@ -458,6 +394,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } + #[cfg(stage0)] unsafe impl ::marker::Sync for Key { } impl Key { @@ -469,14 +406,12 @@ pub const fn new() -> Key { } } - pub fn get(&'static self) -> Option<&'static UnsafeCell>> { - unsafe { - if mem::needs_drop::() && self.dtor_running.get() { - return None - } - self.register_dtor(); + pub unsafe fn get(&self) -> Option<&'static UnsafeCell>> { + if mem::needs_drop::() && self.dtor_running.get() { + return None } - Some(&self.inner) + self.register_dtor(); + Some(&*(&self.inner as *const _)) } unsafe fn register_dtor(&self) { @@ -545,26 +480,24 @@ pub const fn new() -> Key { } } - pub fn get(&'static self) -> Option<&'static UnsafeCell>> { - unsafe { - let ptr = self.os.get() as *mut Value; - if !ptr.is_null() { - if ptr as usize == 1 { - return None - } - return Some(&(*ptr).value); + pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell>> { + let ptr = self.os.get() as *mut Value; + if !ptr.is_null() { + if ptr as usize == 1 { + return None } - - // If the lookup returned null, we haven't initialized our own - // local copy, so do that now. - let ptr: Box> = box Value { - key: self, - value: UnsafeCell::new(None), - }; - let ptr = Box::into_raw(ptr); - self.os.set(ptr as *mut u8); - Some(&(*ptr).value) + return Some(&(*ptr).value); } + + // If the lookup returned null, we haven't initialized our own + // local copy, so do that now. + let ptr: Box> = box Value { + key: self, + value: UnsafeCell::new(None), + }; + let ptr = Box::into_raw(ptr); + self.os.set(ptr as *mut u8); + Some(&(*ptr).value) } }