Skip to content

Commit 29e3d93

Browse files
authored
Merge pull request #286 from briansmith/b/once-ref-dry
DRY `race::OnceRef::{get_or_try_init, set}`.
2 parents 01b1d56 + a206950 commit 29e3d93

File tree

4 files changed

+24
-17
lines changed

4 files changed

+24
-17
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 1.21.3
4+
5+
- Outline more initialization in `race`: [#284](https://github.com/matklad/once_cell/pull/284),
6+
[#285](https://github.com/matklad/once_cell/pull/285).
7+
38
## 1.21.2
49
- Relax success ordering from AcqRel to Release in `race`: [#278](https://github.com/matklad/once_cell/pull/278).
510

Cargo.lock.msrv

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "once_cell"
3-
version = "1.21.2"
3+
version = "1.21.3"
44
authors = ["Aleksey Kladov <[email protected]>"]
55
license = "MIT OR Apache-2.0"
66
edition = "2021"

src/race.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,7 @@ impl<'a, T> OnceRef<'a, T> {
266266
/// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
267267
/// full.
268268
pub fn set(&self, value: &'a T) -> Result<(), ()> {
269-
let ptr = <*const T>::cast_mut(value);
270-
let exchange =
271-
self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::Release, Ordering::Acquire);
272-
match exchange {
269+
match self.compare_exchange(value) {
273270
Ok(_) => Ok(()),
274271
Err(_) => Err(()),
275272
}
@@ -312,19 +309,24 @@ impl<'a, T> OnceRef<'a, T> {
312309
#[cold]
313310
#[inline(never)]
314311
fn init<E>(&self, f: impl FnOnce() -> Result<&'a T, E>) -> Result<&'a T, E> {
315-
let value: &'a T = f()?;
316-
let mut ptr = <*const T>::cast_mut(value);
317-
let exchange = self.inner.compare_exchange(
318-
ptr::null_mut(),
319-
ptr,
320-
Ordering::Release,
321-
Ordering::Acquire,
322-
);
323-
if let Err(old) = exchange {
324-
ptr = old;
312+
let mut value: &'a T = f()?;
313+
if let Err(old) = self.compare_exchange(value) {
314+
value = unsafe { &*old };
325315
}
316+
Ok(value)
317+
}
326318

327-
Ok(unsafe { &*ptr })
319+
#[inline(always)]
320+
fn compare_exchange(&self, value: &'a T) -> Result<(), *const T> {
321+
self.inner
322+
.compare_exchange(
323+
ptr::null_mut(),
324+
<*const T>::cast_mut(value),
325+
Ordering::Release,
326+
Ordering::Acquire,
327+
)
328+
.map(|_: *mut T| ())
329+
.map_err(<*mut T>::cast_const)
328330
}
329331

330332
/// ```compile_fail

0 commit comments

Comments
 (0)