Skip to content

Commit 96adb7d

Browse files
committed
add poisoning documentation to LazyLock
1 parent 37922fc commit 96adb7d

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

library/std/src/sync/lazy_lock.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ union Data<T, F> {
2525
///
2626
/// [`LazyCell`]: crate::cell::LazyCell
2727
///
28+
/// # Poisoning
29+
///
30+
/// If the initialization closure passed to [`LazyLock::new`] panics, the lock will be poisoned.
31+
/// Once the lock is poisoned, any threads that attempt to access this lock (via a dereference
32+
/// or via an explicit call to [`force()`]) will panic.
33+
///
34+
/// This concept is similar to that of poisoning in the [`std::sync::poison`] module. A key
35+
/// difference, however, is that poisoning in `LazyLock` is _unrecoverable_. All future accesses of
36+
/// the lock from other threads will panic, whereas a type in [`std::sync::poison`] like
37+
/// [`std::sync::poison::Mutex`] allows recovery via [`PoisonError::into_inner()`].
38+
///
39+
/// [`force()`]: LazyLock::force
40+
/// [`std::sync::poison`]: crate::sync::poison
41+
/// [`std::sync::poison::Mutex`]: crate::sync::poison::Mutex
42+
/// [`PoisonError::into_inner()`]: crate::sync::poison::PoisonError::into_inner
43+
///
2844
/// # Examples
2945
///
3046
/// Initialize static variables with `LazyLock`.
@@ -102,6 +118,10 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
102118
///
103119
/// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
104120
///
121+
/// # Panics
122+
///
123+
/// Panics if the lock is poisoned.
124+
///
105125
/// # Examples
106126
///
107127
/// ```
@@ -136,6 +156,15 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
136156
/// Forces the evaluation of this lazy value and returns a mutable reference to
137157
/// the result.
138158
///
159+
/// # Panics
160+
///
161+
/// If the initialization closure panics (the one that is passed to the [`new()`] method), the
162+
/// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
163+
/// accesses of the lock (via [`force()`] or a dereference) to panic.
164+
///
165+
/// [`new()`]: LazyLock::new
166+
/// [`force()`]: LazyLock::force
167+
///
139168
/// # Examples
140169
///
141170
/// ```
@@ -193,6 +222,15 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
193222
/// This method will block the calling thread if another initialization
194223
/// routine is currently running.
195224
///
225+
/// # Panics
226+
///
227+
/// If the initialization closure panics (the one that is passed to the [`new()`] method), the
228+
/// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
229+
/// accesses of the lock (via [`force()`] or a dereference) to panic.
230+
///
231+
/// [`new()`]: LazyLock::new
232+
/// [`force()`]: LazyLock::force
233+
///
196234
/// # Examples
197235
///
198236
/// ```
@@ -227,7 +265,8 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
227265
}
228266

229267
impl<T, F> LazyLock<T, F> {
230-
/// Returns a mutable reference to the value if initialized, or `None` if not.
268+
/// Returns a mutable reference to the value if initialized. Otherwise (if uninitialized or
269+
/// poisoned), returns `None`.
231270
///
232271
/// # Examples
233272
///
@@ -256,7 +295,8 @@ impl<T, F> LazyLock<T, F> {
256295
}
257296
}
258297

259-
/// Returns a reference to the value if initialized, or `None` if not.
298+
/// Returns a reference to the value if initialized. Otherwise (if uninitialized or poisoned),
299+
/// returns `None`.
260300
///
261301
/// # Examples
262302
///
@@ -307,6 +347,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
307347
/// This method will block the calling thread if another initialization
308348
/// routine is currently running.
309349
///
350+
/// # Panics
351+
///
352+
/// If the initialization closure panics (the one that is passed to the [`new()`] method), the
353+
/// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
354+
/// accesses of the lock (via [`force()`] or a dereference) to panic.
355+
///
356+
/// [`new()`]: LazyLock::new
357+
/// [`force()`]: LazyLock::force
310358
#[inline]
311359
fn deref(&self) -> &T {
312360
LazyLock::force(self)
@@ -315,6 +363,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
315363

316364
#[stable(feature = "lazy_deref_mut", since = "1.89.0")]
317365
impl<T, F: FnOnce() -> T> DerefMut for LazyLock<T, F> {
366+
/// # Panics
367+
///
368+
/// If the initialization closure panics (the one that is passed to the [`new()`] method), the
369+
/// panic is propagated to the caller, and the lock becomes poisoned. This will cause all future
370+
/// accesses of the lock (via [`force()`] or a dereference) to panic.
371+
///
372+
/// [`new()`]: LazyLock::new
373+
/// [`force()`]: LazyLock::force
318374
#[inline]
319375
fn deref_mut(&mut self) -> &mut T {
320376
LazyLock::force_mut(self)

0 commit comments

Comments
 (0)