aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2023-02-17 07:35:53 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-02-17 07:35:53 +0000
commitc82e56c12cc39d4be674988d184c4e393f99fdc8 (patch)
treef0df62c2365cf1af4985701b56e920f31df686ec
parent6589fbbfd0194f2cdba5d66103864c097c912916 (diff)
parenta4ccd08bab334e94b94bc74b13b1de1e6b36a4d7 (diff)
downloadonce_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.json2
-rw-r--r--Android.bp6
-rw-r--r--CHANGELOG.md4
-rw-r--r--Cargo.toml2
-rw-r--r--Cargo.toml.orig2
-rw-r--r--METADATA6
-rw-r--r--src/lib.rs5
-rw-r--r--src/race.rs47
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
diff --git a/Android.bp b/Android.bp
index 8ccac56..0b618cd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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`.
diff --git a/Cargo.toml b/Cargo.toml
index d2d7f19..76a6291 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/METADATA b/METADATA
index 61e5516..79a823c 100644
--- a/METADATA
+++ b/METADATA
@@ -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
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 83149ac..c2061f8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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