diff options
| author | Lee Bousfield <ljbousfield@gmail.com> | 2017-07-10 19:26:11 -0400 |
|---|---|---|
| committer | Lee Bousfield <ljbousfield@gmail.com> | 2017-07-10 19:26:11 -0400 |
| commit | 32ae12b3d1062babf4f052db42c649e30b11673a (patch) | |
| tree | 682061b739399c2e0efd62dbdbf300cc5611af21 /src/libstd/thread | |
| parent | eb9dfb8bd9444d01fc129bfaac180b913299486b (diff) | |
| download | rust-32ae12b3d1062babf4f052db42c649e30b11673a.tar.gz rust-32ae12b3d1062babf4f052db42c649e30b11673a.zip | |
Add LocalKey::try_with as an alternative to state
Diffstat (limited to 'src/libstd/thread')
| -rw-r--r-- | src/libstd/thread/local.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index dad21473eae..18979fbbdbe 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -232,6 +232,32 @@ pub enum LocalKeyState { Destroyed, } +/// An error returned by [`LocalKey::try_with`](struct.LocalKey.html#method.try_with). +#[unstable(feature = "thread_local_state", + reason = "state querying was recently added", + issue = "27716")] +pub struct AccessError { + _private: (), +} + +#[unstable(feature = "thread_local_state", + reason = "state querying was recently added", + issue = "27716")] +impl fmt::Debug for AccessError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("AccessError").finish() + } +} + +#[unstable(feature = "thread_local_state", + reason = "state querying was recently added", + issue = "27716")] +impl fmt::Display for AccessError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt("already destroyed", f) + } +} + impl<T: 'static> LocalKey<T> { #[doc(hidden)] #[unstable(feature = "thread_local_internals", @@ -331,6 +357,32 @@ impl<T: 'static> LocalKey<T> { } } } + + /// Acquires a reference to the value in this TLS key. + /// + /// This will lazily initialize the value if this thread has not referenced + /// this key yet. If the key has been destroyed (which may happen if this is called + /// in a destructor), this function will return a ThreadLocalError. + /// + /// # Panics + /// + /// This function will still `panic!()` if the key is uninitialized and the + /// key's initializer panics. + #[unstable(feature = "thread_local_state", + reason = "state querying was recently added", + issue = "27716")] + pub fn try_with<F, R>(&'static self, f: F) -> Result<R, AccessError> + where F: FnOnce(&T) -> R { + unsafe { + let slot = (self.inner)().ok_or(AccessError { + _private: (), + })?; + Ok(f(match *slot.get() { + Some(ref inner) => inner, + None => self.init(slot), + })) + } + } } #[doc(hidden)] |
