diff options
author | Jeff Vander Stoep <jeffv@google.com> | 2023-02-17 07:35:53 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-02-17 07:35:53 +0000 |
commit | c82e56c12cc39d4be674988d184c4e393f99fdc8 (patch) | |
tree | f0df62c2365cf1af4985701b56e920f31df686ec | |
parent | 6589fbbfd0194f2cdba5d66103864c097c912916 (diff) | |
parent | a4ccd08bab334e94b94bc74b13b1de1e6b36a4d7 (diff) | |
download | once_cell-c82e56c12cc39d4be674988d184c4e393f99fdc8.tar.gz |
Upgrade once_cell to 1.17.1 am: 1da3db55c9 am: a4ccd08bab
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/once_cell/+/2440588
Change-Id: I60d566b5b734aa706574d3f5e6b51242e218c3f4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 6 | ||||
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/race.rs | 47 |
8 files changed, 52 insertions, 22 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 1d9d16c..8f875ed 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "85e372f818fc07c3688ef431b8735778b4b9430b" + "sha1": "35148638c54c6233545c65d1a5e09d5ba0661806" }, "path_in_vcs": "" }
\ No newline at end of file @@ -42,7 +42,7 @@ rust_library { host_supported: true, crate_name: "once_cell", cargo_env_compat: true, - cargo_pkg_version: "1.17.0", + cargo_pkg_version: "1.17.1", srcs: ["src/lib.rs"], edition: "2021", features: [ @@ -84,7 +84,7 @@ rust_test { host_supported: true, crate_name: "once_cell", cargo_env_compat: true, - cargo_pkg_version: "1.17.0", + cargo_pkg_version: "1.17.1", srcs: ["src/lib.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -110,7 +110,7 @@ rust_test { host_supported: true, crate_name: "it", cargo_env_compat: true, - cargo_pkg_version: "1.17.0", + cargo_pkg_version: "1.17.1", srcs: ["tests/it.rs"], test_suites: ["general-tests"], auto_gen_config: true, diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f3a862..bf489b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - +## 1.17.1 + +- Make `OnceRef` implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). + ## 1.17.0 - Add `race::OnceRef` for storing a `&'a T`. @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.56" name = "once_cell" -version = "1.17.0" +version = "1.17.1" authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"] exclude = [ "*.png", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 5ceec5e..ad02c34 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "once_cell" -version = "1.17.0" +version = "1.17.1" authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"] license = "MIT OR Apache-2.0" edition = "2021" @@ -11,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/once_cell/once_cell-1.17.0.crate" + value: "https://static.crates.io/crates/once_cell/once_cell-1.17.1.crate" } - version: "1.17.0" + version: "1.17.1" license_type: NOTICE last_upgrade_date { year: 2023 month: 2 - day: 3 + day: 16 } } @@ -454,7 +454,10 @@ pub mod unsync { /// Returns `None` if the cell is empty. #[inline] pub fn get(&self) -> Option<&T> { - // Safe due to `inner`'s invariant + // Safe due to `inner`'s invariant of being written to at most once. + // Had multiple writes to `inner` been allowed, a reference to the + // value we return now would become dangling by a write of a + // different value later. unsafe { &*self.inner.get() }.as_ref() } diff --git a/src/race.rs b/src/race.rs index dff5847..ee3d51a 100644 --- a/src/race.rs +++ b/src/race.rs @@ -24,10 +24,11 @@ use atomic_polyfill as atomic; #[cfg(not(feature = "critical-section"))] use core::sync::atomic; -use atomic::{AtomicUsize, Ordering}; +use atomic::{AtomicPtr, AtomicUsize, Ordering}; use core::cell::UnsafeCell; use core::marker::PhantomData; use core::num::NonZeroUsize; +use core::ptr; /// A thread-safe cell which can be written to only once. #[derive(Default, Debug)] @@ -176,7 +177,7 @@ impl OnceBool { /// A thread-safe cell which can be written to only once. pub struct OnceRef<'a, T> { - inner: OnceNonZeroUsize, + inner: AtomicPtr<T>, ghost: PhantomData<UnsafeCell<&'a T>>, } @@ -198,12 +199,13 @@ impl<'a, T> Default for OnceRef<'a, T> { impl<'a, T> OnceRef<'a, T> { /// Creates a new empty cell. pub const fn new() -> OnceRef<'a, T> { - OnceRef { inner: OnceNonZeroUsize::new(), ghost: PhantomData } + OnceRef { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } } /// Gets a reference to the underlying value. pub fn get(&self) -> Option<&'a T> { - self.inner.get().map(|ptr| unsafe { &*(ptr.get() as *const T) }) + let ptr = self.inner.load(Ordering::Acquire); + unsafe { ptr.as_ref() } } /// Sets the contents of this cell to `value`. @@ -211,8 +213,13 @@ impl<'a, T> OnceRef<'a, T> { /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was /// full. pub fn set(&self, value: &'a T) -> Result<(), ()> { - let ptr = NonZeroUsize::new(value as *const T as usize).unwrap(); - self.inner.set(ptr) + let ptr = value as *const T as *mut T; + let exchange = + self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire); + match exchange { + Ok(_) => Ok(()), + Err(_) => Err(()), + } } /// Gets the contents of the cell, initializing it with `f` if the cell was @@ -225,9 +232,11 @@ impl<'a, T> OnceRef<'a, T> { where F: FnOnce() -> &'a T, { - let f = || NonZeroUsize::new(f() as *const T as usize).unwrap(); - let ptr = self.inner.get_or_init(f); - unsafe { &*(ptr.get() as *const T) } + enum Void {} + match self.get_or_try_init(|| Ok::<&'a T, Void>(f())) { + Ok(val) => val, + Err(void) => match void {}, + } } /// Gets the contents of the cell, initializing it with `f` if @@ -241,9 +250,23 @@ impl<'a, T> OnceRef<'a, T> { where F: FnOnce() -> Result<&'a T, E>, { - let f = || f().map(|value| NonZeroUsize::new(value as *const T as usize).unwrap()); - let ptr = self.inner.get_or_try_init(f)?; - unsafe { Ok(&*(ptr.get() as *const T)) } + let mut ptr = self.inner.load(Ordering::Acquire); + + if ptr.is_null() { + // TODO replace with `cast_mut` when MSRV reaches 1.65.0 (also in `set`) + ptr = f()? as *const T as *mut T; + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if let Err(old) = exchange { + ptr = old; + } + } + + Ok(unsafe { &*ptr }) } /// ```compile_fail |