|
| 1 | +//! Synchronization objects that employ poisoning. |
| 2 | +//! |
| 3 | +//! # Poisoning |
| 4 | +//! |
| 5 | +//! All synchronization objects in this module implement a strategy called "poisoning" |
| 6 | +//! where if a thread panics while holding the exclusive access granted by the primitive, |
| 7 | +//! the state of the primitive is set to "poisoned". |
| 8 | +//! This information is then propagated to all other threads |
| 9 | +//! to signify that the data protected by this primitive is likely tainted |
| 10 | +//! (some invariant is not being upheld). |
| 11 | +//! |
| 12 | +//! The specifics of how this "poisoned" state affects other threads |
| 13 | +//! depend on the primitive. See [#Overview] bellow. |
| 14 | +//! |
| 15 | +//! For the alternative implementations that do not employ poisoning, |
| 16 | +//! see `std::sys::nonpoisoning`. |
| 17 | +//! |
| 18 | +//! # Overview |
| 19 | +//! |
| 20 | +//! Below is a list of synchronization objects provided by this module |
| 21 | +//! with a high-level overview for each object and a description |
| 22 | +//! of how it employs "poisoning". |
| 23 | +//! |
| 24 | +//! - [`Condvar`]: Condition Variable, providing the ability to block |
| 25 | +//! a thread while waiting for an event to occur. |
| 26 | +//! |
| 27 | +//! Condition variables are typically associated with |
| 28 | +//! a boolean predicate (a condition) and a mutex. |
| 29 | +//! This implementation is associated with [`poison::Mutex`](Mutex), |
| 30 | +//! which employs poisoning. |
| 31 | +//! For this reason, [`Condvar::wait()`] will return a [`LockResult`], |
| 32 | +//! just like [`poison::Mutex::lock()`](Mutex::lock) does. |
| 33 | +//! |
| 34 | +//! - [`Mutex`]: Mutual Exclusion mechanism, which ensures that at |
| 35 | +//! most one thread at a time is able to access some data. |
| 36 | +//! |
| 37 | +//! [`Mutex::lock()`] returns a [`LockResult`], |
| 38 | +//! providing a way to deal with the poisoned state. |
| 39 | +//! See [`Mutex`'s documentation](Mutex#poisoning) for more. |
| 40 | +//! |
| 41 | +//! - [`Once`]: A thread-safe way to run a piece of code only once. |
| 42 | +//! Mostly useful for implementing one-time global initialization. |
| 43 | +//! |
| 44 | +//! [`Once`] is poisoned if the piece of code passed to |
| 45 | +//! [`Once::call_once()`] or [`Once::call_once_force()`] panics. |
| 46 | +//! When in poisoned state, subsequent calls to [`Once::call_once()`] will panic too. |
| 47 | +//! [`Once::call_once_force()`] can be used to clear the poisoned state. |
| 48 | +//! |
| 49 | +//! - [`RwLock`]: Provides a mutual exclusion mechanism which allows |
| 50 | +//! multiple readers at the same time, while allowing only one |
| 51 | +//! writer at a time. In some cases, this can be more efficient than |
| 52 | +//! a mutex. |
| 53 | +//! |
| 54 | +//! This implementation, like [`Mutex`], will become poisoned on a panic. |
| 55 | +//! Note, however, that an `RwLock` may only be poisoned if a panic occurs |
| 56 | +//! while it is locked exclusively (write mode). If a panic occurs in any reader, |
| 57 | +//! then the lock will not be poisoned. |
| 58 | +
|
| 59 | +// FIXME(sync_nonpoison) add links to sync::nonpoison to the doc comment above. |
| 60 | + |
| 61 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 62 | +pub use self::condvar::{Condvar, WaitTimeoutResult}; |
| 63 | +#[unstable(feature = "mapped_lock_guards", issue = "117108")] |
| 64 | +pub use self::mutex::MappedMutexGuard; |
| 65 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 66 | +pub use self::mutex::{Mutex, MutexGuard}; |
| 67 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 68 | +#[expect(deprecated)] |
| 69 | +pub use self::once::ONCE_INIT; |
| 70 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 71 | +pub use self::once::{Once, OnceState}; |
| 72 | +#[unstable(feature = "mapped_lock_guards", issue = "117108")] |
| 73 | +pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; |
| 74 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 75 | +pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; |
1 | 76 | use crate::error::Error;
|
2 | 77 | use crate::fmt;
|
3 | 78 | #[cfg(panic = "unwind")]
|
4 | 79 | use crate::sync::atomic::{AtomicBool, Ordering};
|
5 | 80 | #[cfg(panic = "unwind")]
|
6 | 81 | use crate::thread;
|
7 | 82 |
|
8 |
| -pub struct Flag { |
| 83 | +mod condvar; |
| 84 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 85 | +mod mutex; |
| 86 | +pub(crate) mod once; |
| 87 | +mod rwlock; |
| 88 | + |
| 89 | +pub(crate) struct Flag { |
9 | 90 | #[cfg(panic = "unwind")]
|
10 | 91 | failed: AtomicBool,
|
11 | 92 | }
|
@@ -78,7 +159,7 @@ impl Flag {
|
78 | 159 | }
|
79 | 160 |
|
80 | 161 | #[derive(Clone)]
|
81 |
| -pub struct Guard { |
| 162 | +pub(crate) struct Guard { |
82 | 163 | #[cfg(panic = "unwind")]
|
83 | 164 | panicking: bool,
|
84 | 165 | }
|
@@ -316,7 +397,7 @@ impl<T> Error for TryLockError<T> {
|
316 | 397 | }
|
317 | 398 | }
|
318 | 399 |
|
319 |
| -pub fn map_result<T, U, F>(result: LockResult<T>, f: F) -> LockResult<U> |
| 400 | +pub(crate) fn map_result<T, U, F>(result: LockResult<T>, f: F) -> LockResult<U> |
320 | 401 | where
|
321 | 402 | F: FnOnce(T) -> U,
|
322 | 403 | {
|
|
0 commit comments