diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-04-14 09:01:56 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-14 09:01:56 +0200 |
| commit | 7c8c2f08e16ede8fcdbeab50b9fd508f203c61b4 (patch) | |
| tree | edc783c96a218afc022277c9ce55cd04426ea4fe /library/std/src/thread | |
| parent | f3c66088610c1b80110297c2d9a8b5f9265b013f (diff) | |
| parent | 313085f7258ef86cf190aa6c234a42843995fdbc (diff) | |
| download | rust-7c8c2f08e16ede8fcdbeab50b9fd508f203c61b4.tar.gz rust-7c8c2f08e16ede8fcdbeab50b9fd508f203c61b4.zip | |
Rollup merge of #123651 - tgross35:thread-local-updates, r=Mark-Simulacrum
Thread local updates for idiomatic examples Update thread local examples to make more idiomatic use of `Cell` for `Copy` types, `RefCell` for non-`Copy` types. Also shrink the size of `unsafe` blocks, add `SAFETY` comments, and fix `clippy::redundant_closure_for_method_calls`.
Diffstat (limited to 'library/std/src/thread')
| -rw-r--r-- | library/std/src/thread/local.rs | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index fbb882e640b..c1b4440e560 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -53,25 +53,25 @@ use crate::fmt; /// # Examples /// /// ``` -/// use std::cell::RefCell; +/// use std::cell::Cell; /// use std::thread; /// -/// thread_local!(static FOO: RefCell<u32> = RefCell::new(1)); +/// thread_local!(static FOO: Cell<u32> = Cell::new(1)); /// -/// FOO.with_borrow(|v| assert_eq!(*v, 1)); -/// FOO.with_borrow_mut(|v| *v = 2); +/// assert_eq!(FOO.get(), 1); +/// FOO.set(2); /// /// // each thread starts out with the initial value of 1 /// let t = thread::spawn(move|| { -/// FOO.with_borrow(|v| assert_eq!(*v, 1)); -/// FOO.with_borrow_mut(|v| *v = 3); +/// assert_eq!(FOO.get(), 1); +/// FOO.set(3); /// }); /// /// // wait for the thread to complete and bail out on panic /// t.join().unwrap(); /// /// // we retain our original value of 2 despite the child thread -/// FOO.with_borrow(|v| assert_eq!(*v, 2)); +/// assert_eq!(FOO.get(), 2); /// ``` /// /// # Platform-specific behavior @@ -141,15 +141,16 @@ impl<T: 'static> fmt::Debug for LocalKey<T> { /// Publicity and attributes for each static are allowed. Example: /// /// ``` -/// use std::cell::RefCell; +/// use std::cell::{Cell, RefCell}; +/// /// thread_local! { -/// pub static FOO: RefCell<u32> = RefCell::new(1); +/// pub static FOO: Cell<u32> = Cell::new(1); /// -/// static BAR: RefCell<f32> = RefCell::new(1.0); +/// static BAR: RefCell<Vec<f32>> = RefCell::new(vec![1.0, 2.0]); /// } /// -/// FOO.with_borrow(|v| assert_eq!(*v, 1)); -/// BAR.with_borrow(|v| assert_eq!(*v, 1.0)); +/// assert_eq!(FOO.get(), 1); +/// BAR.with_borrow(|v| assert_eq!(v[1], 2.0)); /// ``` /// /// Note that only shared references (`&T`) to the inner data may be obtained, so a @@ -164,12 +165,13 @@ impl<T: 'static> fmt::Debug for LocalKey<T> { /// track any additional state. /// /// ``` -/// use std::cell::Cell; +/// use std::cell::RefCell; +/// /// thread_local! { -/// pub static FOO: Cell<u32> = const { Cell::new(1) }; +/// pub static FOO: RefCell<Vec<u32>> = const { RefCell::new(Vec::new()) }; /// } /// -/// assert_eq!(FOO.get(), 1); +/// FOO.with_borrow(|v| assert_eq!(v.len(), 0)); /// ``` /// /// See [`LocalKey` documentation][`std::thread::LocalKey`] for more @@ -279,10 +281,9 @@ impl<T: 'static> LocalKey<T> { where F: FnOnce(&T) -> R, { - unsafe { - let thread_local = (self.inner)(None).ok_or(AccessError)?; - Ok(f(thread_local)) - } + // SAFETY: `inner` is safe to call within the lifetime of the thread + let thread_local = unsafe { (self.inner)(None).ok_or(AccessError)? }; + Ok(f(thread_local)) } /// Acquires a reference to the value in this TLS key, initializing it with @@ -301,14 +302,17 @@ impl<T: 'static> LocalKey<T> { where F: FnOnce(Option<T>, &T) -> R, { - unsafe { - let mut init = Some(init); - let reference = (self.inner)(Some(&mut init)).expect( + let mut init = Some(init); + + // SAFETY: `inner` is safe to call within the lifetime of the thread + let reference = unsafe { + (self.inner)(Some(&mut init)).expect( "cannot access a Thread Local Storage value \ during or after destruction", - ); - f(init, reference) - } + ) + }; + + f(init, reference) } } @@ -377,7 +381,7 @@ impl<T: 'static> LocalKey<Cell<T>> { where T: Copy, { - self.with(|cell| cell.get()) + self.with(Cell::get) } /// Takes the contained value, leaving `Default::default()` in its place. @@ -407,7 +411,7 @@ impl<T: 'static> LocalKey<Cell<T>> { where T: Default, { - self.with(|cell| cell.take()) + self.with(Cell::take) } /// Replaces the contained value, returning the old value. @@ -578,7 +582,7 @@ impl<T: 'static> LocalKey<RefCell<T>> { where T: Default, { - self.with(|cell| cell.take()) + self.with(RefCell::take) } /// Replaces the contained value, returning the old value. |
