Remove an old custom OnceCell implementation in favor of std (#7208)

This commit is contained in:
Alphyr
2025-03-11 08:15:26 +01:00
committed by GitHub
parent 7efcab43c9
commit 8507e28f89
5 changed files with 10 additions and 83 deletions
@@ -1,10 +1,10 @@
use super::AtomicU64;
use crate::loom::sync::{atomic::Ordering, Mutex};
use crate::util::once_cell::OnceCell;
use std::sync::OnceLock;
pub(crate) struct StaticAtomicU64 {
init: u64,
cell: OnceCell<Mutex<u64>>,
cell: OnceLock<Mutex<u64>>,
}
impl AtomicU64 {
@@ -19,7 +19,7 @@ impl StaticAtomicU64 {
pub(crate) const fn new(val: u64) -> StaticAtomicU64 {
StaticAtomicU64 {
init: val,
cell: OnceCell::new(),
cell: OnceLock::new(),
}
}
@@ -52,6 +52,6 @@ impl StaticAtomicU64 {
}
fn inner(&self) -> &Mutex<u64> {
self.cell.get(|| Mutex::new(self.init))
self.cell.get_or_init(|| Mutex::new(self.init))
}
}
+3 -3
View File
@@ -66,11 +66,11 @@ impl Kill for StdChild {
cfg_not_has_const_mutex_new! {
fn get_orphan_queue() -> &'static OrphanQueueImpl<StdChild> {
use crate::util::once_cell::OnceCell;
use std::sync::OnceLock;
static ORPHAN_QUEUE: OnceCell<OrphanQueueImpl<StdChild>> = OnceCell::new();
static ORPHAN_QUEUE: OnceLock<OrphanQueueImpl<StdChild>> = OnceLock::new();
ORPHAN_QUEUE.get(OrphanQueueImpl::new)
ORPHAN_QUEUE.get_or_init(OrphanQueueImpl::new)
}
}
+3 -3
View File
@@ -1,9 +1,9 @@
use crate::signal::os::{OsExtraData, OsStorage};
use crate::sync::watch;
use crate::util::once_cell::OnceCell;
use std::ops;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock;
pub(crate) type EventId = usize;
@@ -164,9 +164,9 @@ where
OsExtraData: 'static + Send + Sync + Init,
OsStorage: 'static + Send + Sync + Init,
{
static GLOBALS: OnceCell<Globals> = OnceCell::new();
static GLOBALS: OnceLock<Globals> = OnceLock::new();
GLOBALS.get(globals_init)
GLOBALS.get_or_init(globals_init)
}
#[cfg(all(test, not(loom)))]
-3
View File
@@ -13,9 +13,6 @@ pub(crate) use blocking_check::check_socket_for_blocking;
pub(crate) mod metric_atomics;
#[cfg(any(feature = "rt", feature = "signal", feature = "process"))]
pub(crate) mod once_cell;
#[cfg(any(
// io driver uses `WakeList` directly
feature = "net",
-70
View File
@@ -1,70 +0,0 @@
#![allow(dead_code)]
use std::cell::UnsafeCell;
use std::mem::MaybeUninit;
use std::sync::Once;
pub(crate) struct OnceCell<T> {
once: Once,
value: UnsafeCell<MaybeUninit<T>>,
}
unsafe impl<T: Send + Sync> Send for OnceCell<T> {}
unsafe impl<T: Send + Sync> Sync for OnceCell<T> {}
impl<T> OnceCell<T> {
pub(crate) const fn new() -> Self {
Self {
once: Once::new(),
value: UnsafeCell::new(MaybeUninit::uninit()),
}
}
/// Get the value inside this cell, initializing it using the provided
/// function if necessary.
///
/// If the `init` closure panics, then the `OnceCell` is poisoned and all
/// future calls to `get` will panic.
#[inline]
pub(crate) fn get(&self, init: impl FnOnce() -> T) -> &T {
if !self.once.is_completed() {
self.do_init(init);
}
// Safety: The `std::sync::Once` guarantees that we can only reach this
// line if a `call_once` closure has been run exactly once and without
// panicking. Thus, the value is not uninitialized.
//
// There is also no race because the only `&self` method that modifies
// `value` is `do_init`, but if the `call_once` closure is still
// running, then no thread has gotten past the `call_once`.
unsafe { &*(self.value.get() as *const T) }
}
#[cold]
fn do_init(&self, init: impl FnOnce() -> T) {
let value_ptr = self.value.get() as *mut T;
self.once.call_once(|| {
let set_to = init();
// Safety: The `std::sync::Once` guarantees that this initialization
// will run at most once, and that no thread can get past the
// `call_once` until it has run exactly once. Thus, we have
// exclusive access to `value`.
unsafe {
std::ptr::write(value_ptr, set_to);
}
});
}
}
impl<T> Drop for OnceCell<T> {
fn drop(&mut self) {
if self.once.is_completed() {
let value_ptr = self.value.get() as *mut T;
unsafe {
std::ptr::drop_in_place(value_ptr);
}
}
}
}