about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authorLee Bousfield <ljbousfield@gmail.com>2017-07-10 19:26:11 -0400
committerLee Bousfield <ljbousfield@gmail.com>2017-07-10 19:26:11 -0400
commit32ae12b3d1062babf4f052db42c649e30b11673a (patch)
tree682061b739399c2e0efd62dbdbf300cc5611af21 /src/libstd/thread
parenteb9dfb8bd9444d01fc129bfaac180b913299486b (diff)
downloadrust-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.rs52
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)]