Skip to content

Commit ef16d45

Browse files
committed
move once module out of poison
Since `Once` will not have a non-poisoning variant, we remove it from the `poison` module. Additionally: 1. Renames `once::ExclusiveState` to `OnceExclusiveState` since it was a bit confusing reading just `ExclusiveState` where it is used. 2. Reorders a few module definitions and re-exports in `library/std/src/sync/mod.rs` for clarity. Signed-off-by: Connor Tsui <[email protected]>
1 parent 4ffeda1 commit ef16d45

File tree

7 files changed

+92
-88
lines changed

7 files changed

+92
-88
lines changed

library/std/src/sync/lazy_lock.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::poison::once::ExclusiveState;
1+
use super::once::OnceExclusiveState;
22
use crate::cell::UnsafeCell;
33
use crate::mem::ManuallyDrop;
44
use crate::ops::{Deref, DerefMut};
@@ -140,14 +140,18 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
140140
pub fn into_inner(mut this: Self) -> Result<T, F> {
141141
let state = this.once.state();
142142
match state {
143-
ExclusiveState::Poisoned => panic_poisoned(),
143+
OnceExclusiveState::Poisoned => panic_poisoned(),
144144
state => {
145145
let this = ManuallyDrop::new(this);
146146
let data = unsafe { ptr::read(&this.data) }.into_inner();
147147
match state {
148-
ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })),
149-
ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })),
150-
ExclusiveState::Poisoned => unreachable!(),
148+
OnceExclusiveState::Incomplete => {
149+
Err(ManuallyDrop::into_inner(unsafe { data.f }))
150+
}
151+
OnceExclusiveState::Complete => {
152+
Ok(ManuallyDrop::into_inner(unsafe { data.value }))
153+
}
154+
OnceExclusiveState::Poisoned => unreachable!(),
151155
}
152156
}
153157
}
@@ -189,7 +193,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
189193
impl<T, F> Drop for PoisonOnPanic<'_, T, F> {
190194
#[inline]
191195
fn drop(&mut self) {
192-
self.0.once.set_state(ExclusiveState::Poisoned);
196+
self.0.once.set_state(OnceExclusiveState::Poisoned);
193197
}
194198
}
195199

@@ -200,19 +204,19 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
200204
let guard = PoisonOnPanic(this);
201205
let data = f();
202206
guard.0.data.get_mut().value = ManuallyDrop::new(data);
203-
guard.0.once.set_state(ExclusiveState::Complete);
207+
guard.0.once.set_state(OnceExclusiveState::Complete);
204208
core::mem::forget(guard);
205209
// SAFETY: We put the value there above.
206210
unsafe { &mut this.data.get_mut().value }
207211
}
208212

209213
let state = this.once.state();
210214
match state {
211-
ExclusiveState::Poisoned => panic_poisoned(),
215+
OnceExclusiveState::Poisoned => panic_poisoned(),
212216
// SAFETY: The `Once` states we completed the initialization.
213-
ExclusiveState::Complete => unsafe { &mut this.data.get_mut().value },
217+
OnceExclusiveState::Complete => unsafe { &mut this.data.get_mut().value },
214218
// SAFETY: The state is `Incomplete`.
215-
ExclusiveState::Incomplete => unsafe { really_init_mut(this) },
219+
OnceExclusiveState::Incomplete => unsafe { really_init_mut(this) },
216220
}
217221
}
218222

@@ -293,7 +297,7 @@ impl<T, F> LazyLock<T, F> {
293297
match state {
294298
// SAFETY:
295299
// The closure has been run successfully, so `value` has been initialized.
296-
ExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }),
300+
OnceExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }),
297301
_ => None,
298302
}
299303
}
@@ -332,11 +336,13 @@ impl<T, F> LazyLock<T, F> {
332336
impl<T, F> Drop for LazyLock<T, F> {
333337
fn drop(&mut self) {
334338
match self.once.state() {
335-
ExclusiveState::Incomplete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().f) },
336-
ExclusiveState::Complete => unsafe {
339+
OnceExclusiveState::Incomplete => unsafe {
340+
ManuallyDrop::drop(&mut self.data.get_mut().f)
341+
},
342+
OnceExclusiveState::Complete => unsafe {
337343
ManuallyDrop::drop(&mut self.data.get_mut().value)
338344
},
339-
ExclusiveState::Poisoned => {}
345+
OnceExclusiveState::Poisoned => {}
340346
}
341347
}
342348
}

library/std/src/sync/mod.rs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@
142142
//! most one thread at a time is able to access some data.
143143
//!
144144
//! - [`Once`]: Used for a thread-safe, one-time global initialization routine.
145-
//! Mostly useful for implementing other types like `OnceLock`.
145+
//! Mostly useful for implementing other types like [`OnceLock`].
146146
//!
147147
//! - [`OnceLock`]: Used for thread-safe, one-time initialization of a
148148
//! variable, with potentially different initializers based on the caller.
@@ -181,10 +181,20 @@ pub use alloc_crate::sync::UniqueArc;
181181
#[stable(feature = "rust1", since = "1.0.0")]
182182
pub use alloc_crate::sync::{Arc, Weak};
183183

184-
// FIXME(sync_nonpoison,sync_poison_mod): remove all `#[doc(inline)]` once the modules are stabilized.
184+
#[unstable(feature = "mpmc_channel", issue = "126840")]
185+
pub mod mpmc;
186+
pub mod mpsc;
187+
188+
mod once;
189+
mod barrier;
190+
mod lazy_lock;
191+
mod once_lock;
192+
mod reentrant_lock;
185193

186194
// These exist only in one flavor: no poisoning.
187195
#[stable(feature = "rust1", since = "1.0.0")]
196+
pub use self::once::{Once, OnceState};
197+
#[stable(feature = "rust1", since = "1.0.0")]
188198
pub use self::barrier::{Barrier, BarrierWaitResult};
189199
#[stable(feature = "lazy_cell", since = "1.80.0")]
190200
pub use self::lazy_lock::LazyLock;
@@ -193,47 +203,42 @@ pub use self::once_lock::OnceLock;
193203
#[unstable(feature = "reentrant_lock", issue = "121440")]
194204
pub use self::reentrant_lock::{ReentrantLock, ReentrantLockGuard};
195205

196-
// These make sense and exist only with poisoning.
206+
#[stable(feature = "rust1", since = "1.0.0")]
207+
#[expect(deprecated)]
208+
pub use self::once::ONCE_INIT;
209+
210+
// Used for `sys::sync::once` implementations and `LazyLock` implementation.
211+
pub(crate) use self::once::OnceExclusiveState;
212+
213+
// FIXME(sync_poison_mod): remove all `#[doc(inline)]` once the modules are stabilized.
214+
215+
#[unstable(feature = "sync_poison_mod", issue = "134646")]
216+
pub mod poison;
217+
#[unstable(feature = "sync_nonpoison", issue = "134645")]
218+
pub mod nonpoison;
219+
220+
// These exist only with poisoning.
197221
#[stable(feature = "rust1", since = "1.0.0")]
198222
#[doc(inline)]
199223
pub use self::poison::{LockResult, PoisonError};
200224

201-
// These (should) exist in both flavors: with and without poisoning.
202-
// FIXME(sync_nonpoison): implement nonpoison versions:
203-
// * Mutex (nonpoison_mutex)
204-
// * Condvar (nonpoison_condvar)
205-
// * Once (nonpoison_once)
206-
// * RwLock (nonpoison_rwlock)
225+
// These exist in both flavors: with and without poisoning.
207226
// The historical default is the version with poisoning.
208227
#[stable(feature = "rust1", since = "1.0.0")]
209228
#[doc(inline)]
210229
pub use self::poison::{
211-
Mutex, MutexGuard, TryLockError, TryLockResult,
230+
TryLockError, TryLockResult,
231+
Mutex, MutexGuard,
212232
Condvar,
213-
Once, OnceState,
214233
RwLock, RwLockReadGuard, RwLockWriteGuard,
215234
};
216-
#[stable(feature = "rust1", since = "1.0.0")]
217-
#[doc(inline)]
218-
#[expect(deprecated)]
219-
pub use self::poison::ONCE_INIT;
235+
220236
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
221237
#[doc(inline)]
222238
pub use self::poison::{MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard};
223239

224-
#[unstable(feature = "mpmc_channel", issue = "126840")]
225-
pub mod mpmc;
226-
pub mod mpsc;
227-
228-
#[unstable(feature = "sync_nonpoison", issue = "134645")]
229-
pub mod nonpoison;
230-
#[unstable(feature = "sync_poison_mod", issue = "134646")]
231-
pub mod poison;
232-
233-
mod barrier;
234-
mod lazy_lock;
235-
mod once_lock;
236-
mod reentrant_lock;
240+
// FIXME(sync_nonpoison): Export non-poisoning locks instead of poisoning locks.
241+
// See: https://github.com/rust-lang/rust/issues/134645#issuecomment-3324577500
237242

238243
/// A type indicating whether a timed wait on a condition variable returned
239244
/// due to a time out or not.

library/std/src/sync/poison/once.rs renamed to library/std/src/sync/once.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ pub struct OnceState {
4949
pub(crate) inner: sys::OnceState,
5050
}
5151

52-
pub(crate) enum ExclusiveState {
52+
/// Used for the internal implementation of `sys::sync::once` on different platforms.
53+
pub(crate) enum OnceExclusiveState {
5354
Incomplete,
5455
Poisoned,
5556
Complete,
@@ -310,7 +311,7 @@ impl Once {
310311
/// be running, so the state must be either "incomplete", "poisoned" or
311312
/// "complete".
312313
#[inline]
313-
pub(crate) fn state(&mut self) -> ExclusiveState {
314+
pub(crate) fn state(&mut self) -> OnceExclusiveState {
314315
self.inner.state()
315316
}
316317

@@ -320,7 +321,7 @@ impl Once {
320321
/// be running, so the state must be either "incomplete", "poisoned" or
321322
/// "complete".
322323
#[inline]
323-
pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
324+
pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) {
324325
self.inner.set_state(new_state);
325326
}
326327
}

library/std/src/sync/poison.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
//! the panics are recognized reliably or on a best-effort basis depend on the
1414
//! primitive. See [Overview](#overview) below.
1515
//!
16-
//! For the alternative implementations that do not employ poisoning,
17-
//! see [`std::sync::nonpoison`].
16+
//! The synchronization objects in this module have alternative implementations that do not employ
17+
//! poisoning on the [`std::sync::nonpoison`] module.
1818
//!
1919
//! [`std::sync::nonpoison`]: crate::sync::nonpoison
2020
//!
@@ -42,14 +42,6 @@
4242
//! [`Mutex::lock()`] returns a [`LockResult`], providing a way to deal with
4343
//! the poisoned state. See [`Mutex`'s documentation](Mutex#poisoning) for more.
4444
//!
45-
//! - [`Once`]: A thread-safe way to run a piece of code only once.
46-
//! Mostly useful for implementing one-time global initialization.
47-
//!
48-
//! [`Once`] is reliably poisoned if the piece of code passed to
49-
//! [`Once::call_once()`] or [`Once::call_once_force()`] panics.
50-
//! When in poisoned state, subsequent calls to [`Once::call_once()`] will panic too.
51-
//! [`Once::call_once_force()`] can be used to clear the poisoned state.
52-
//!
5345
//! - [`RwLock`]: Provides a mutual exclusion mechanism which allows
5446
//! multiple readers at the same time, while allowing only one
5547
//! writer at a time. In some cases, this can be more efficient than
@@ -59,18 +51,19 @@
5951
//! Note, however, that an `RwLock` may only be poisoned if a panic occurs
6052
//! while it is locked exclusively (write mode). If a panic occurs in any reader,
6153
//! then the lock will not be poisoned.
54+
//!
55+
//! Note that the [`Once`] type also employs poisoning, but since it has non-poisoning `force`
56+
//! methods available on it, we do not need to both create a separate `nonpoison::Once` type and
57+
//! also place [`Once`] in this module.
58+
//!
59+
//! [`Once`]: crate::sync::Once
6260
6361
#[stable(feature = "rust1", since = "1.0.0")]
6462
pub use self::condvar::Condvar;
6563
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
6664
pub use self::mutex::MappedMutexGuard;
6765
#[stable(feature = "rust1", since = "1.0.0")]
6866
pub use self::mutex::{Mutex, MutexGuard};
69-
#[stable(feature = "rust1", since = "1.0.0")]
70-
#[expect(deprecated)]
71-
pub use self::once::ONCE_INIT;
72-
#[stable(feature = "rust1", since = "1.0.0")]
73-
pub use self::once::{Once, OnceState};
7467
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
7568
pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard};
7669
#[stable(feature = "rust1", since = "1.0.0")]
@@ -85,7 +78,6 @@ use crate::thread;
8578
mod condvar;
8679
#[stable(feature = "rust1", since = "1.0.0")]
8780
mod mutex;
88-
pub(crate) mod once;
8981
mod rwlock;
9082

9183
pub(crate) struct Flag {

library/std/src/sys/sync/once/futex.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::cell::Cell;
22
use crate::sync as public;
3+
use crate::sync::OnceExclusiveState;
34
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
4-
use crate::sync::poison::once::ExclusiveState;
55
use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all};
66

77
// On some platforms, the OS is very nice and handles the waiter queue for us.
@@ -83,21 +83,21 @@ impl Once {
8383
}
8484

8585
#[inline]
86-
pub(crate) fn state(&mut self) -> ExclusiveState {
86+
pub(crate) fn state(&mut self) -> OnceExclusiveState {
8787
match *self.state_and_queued.get_mut() {
88-
INCOMPLETE => ExclusiveState::Incomplete,
89-
POISONED => ExclusiveState::Poisoned,
90-
COMPLETE => ExclusiveState::Complete,
88+
INCOMPLETE => OnceExclusiveState::Incomplete,
89+
POISONED => OnceExclusiveState::Poisoned,
90+
COMPLETE => OnceExclusiveState::Complete,
9191
_ => unreachable!("invalid Once state"),
9292
}
9393
}
9494

9595
#[inline]
96-
pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
96+
pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) {
9797
*self.state_and_queued.get_mut() = match new_state {
98-
ExclusiveState::Incomplete => INCOMPLETE,
99-
ExclusiveState::Poisoned => POISONED,
100-
ExclusiveState::Complete => COMPLETE,
98+
OnceExclusiveState::Incomplete => INCOMPLETE,
99+
OnceExclusiveState::Poisoned => POISONED,
100+
OnceExclusiveState::Complete => COMPLETE,
101101
};
102102
}
103103

library/std/src/sys/sync/once/no_threads.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::cell::Cell;
22
use crate::sync as public;
3-
use crate::sync::poison::once::ExclusiveState;
3+
use crate::sync::OnceExclusiveState;
44

55
pub struct Once {
66
state: Cell<State>,
@@ -45,21 +45,21 @@ impl Once {
4545
}
4646

4747
#[inline]
48-
pub(crate) fn state(&mut self) -> ExclusiveState {
48+
pub(crate) fn state(&mut self) -> OnceExclusiveState {
4949
match self.state.get() {
50-
State::Incomplete => ExclusiveState::Incomplete,
51-
State::Poisoned => ExclusiveState::Poisoned,
52-
State::Complete => ExclusiveState::Complete,
50+
State::Incomplete => OnceExclusiveState::Incomplete,
51+
State::Poisoned => OnceExclusiveState::Poisoned,
52+
State::Complete => OnceExclusiveState::Complete,
5353
_ => unreachable!("invalid Once state"),
5454
}
5555
}
5656

5757
#[inline]
58-
pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
58+
pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) {
5959
self.state.set(match new_state {
60-
ExclusiveState::Incomplete => State::Incomplete,
61-
ExclusiveState::Poisoned => State::Poisoned,
62-
ExclusiveState::Complete => State::Complete,
60+
OnceExclusiveState::Incomplete => State::Incomplete,
61+
OnceExclusiveState::Poisoned => State::Poisoned,
62+
OnceExclusiveState::Complete => State::Complete,
6363
});
6464
}
6565

library/std/src/sys/sync/once/queue.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@
5656
// allowed, so no need for `SeqCst`.
5757

5858
use crate::cell::Cell;
59+
use crate::sync::OnceExclusiveState;
5960
use crate::sync::atomic::Ordering::{AcqRel, Acquire, Release};
6061
use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr};
61-
use crate::sync::poison::once::ExclusiveState;
6262
use crate::thread::{self, Thread};
6363
use crate::{fmt, ptr, sync as public};
6464

@@ -131,21 +131,21 @@ impl Once {
131131
}
132132

133133
#[inline]
134-
pub(crate) fn state(&mut self) -> ExclusiveState {
134+
pub(crate) fn state(&mut self) -> OnceExclusiveState {
135135
match self.state_and_queue.get_mut().addr() {
136-
INCOMPLETE => ExclusiveState::Incomplete,
137-
POISONED => ExclusiveState::Poisoned,
138-
COMPLETE => ExclusiveState::Complete,
136+
INCOMPLETE => OnceExclusiveState::Incomplete,
137+
POISONED => OnceExclusiveState::Poisoned,
138+
COMPLETE => OnceExclusiveState::Complete,
139139
_ => unreachable!("invalid Once state"),
140140
}
141141
}
142142

143143
#[inline]
144-
pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
144+
pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) {
145145
*self.state_and_queue.get_mut() = match new_state {
146-
ExclusiveState::Incomplete => ptr::without_provenance_mut(INCOMPLETE),
147-
ExclusiveState::Poisoned => ptr::without_provenance_mut(POISONED),
148-
ExclusiveState::Complete => ptr::without_provenance_mut(COMPLETE),
146+
OnceExclusiveState::Incomplete => ptr::without_provenance_mut(INCOMPLETE),
147+
OnceExclusiveState::Poisoned => ptr::without_provenance_mut(POISONED),
148+
OnceExclusiveState::Complete => ptr::without_provenance_mut(COMPLETE),
149149
};
150150
}
151151

0 commit comments

Comments
 (0)