Description
Feature gate: #![feature(once_state_poison_pub)]
This is a tracking issue for making the poison
method of OnceState
public.
The Once
synchronization primitive provides a poison
method for marking the internal OnceState
as poisoned, which is combined with the call_once_force
method in OnceLock::initialize
to call initialization functions until one succeeds without panicking. This provides a way for users to use fallible initialization functions where they only observe the OnceLock
being initialized once a function doesn't panic:
fn initialize<F, E>(&self, f: F) -> Result<(), E>
where
F: FnOnce() -> Result<T, E>,
{
let mut res: Result<(), E> = Ok(());
let slot = &self.value;
// Ignore poisoning from other threads
// If another thread panics, then we'll be able to run our closure
self.once.call_once_force(|p| {
match f() {
Ok(value) => {
unsafe { (&mut *slot.get()).write(value) };
}
Err(e) => {
res = Err(e);
// Treat the underlying `Once` as poisoned since we
// failed to initialize our value.
p.poison();
}
}
});
res
}
This tracking issue is for marking the poison
method on OnceState
as pub
, rather than pub(crate)
. This has no impact on the OnceCell
or OnceLock
APIs, but allows downstream libraries to build out similar functionality. The motivation for this is for the twice-cell
crate, where use of this API would simplify the implementation.
Public API
// std::sync::once
pub struct OnceState {
pub(crate) inner: sys::OnceState,
}
impl OnceState {
/// Poison the associated [`Once`] without explicitly panicking.
#[inline]
pub fn poison(&self) {
self.inner.poison();
}
}
Steps / History
- Implementation: Mark
OnceState::poison
aspub
#130330 - Final comment period (FCP)1
- Stabilization PR
Unresolved Questions
- None yet.