aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sync/once.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ctr-std/src/sync/once.rs')
-rw-r--r--ctr-std/src/sync/once.rs117
1 files changed, 103 insertions, 14 deletions
diff --git a/ctr-std/src/sync/once.rs b/ctr-std/src/sync/once.rs
index c449315..6fd8b6a 100644
--- a/ctr-std/src/sync/once.rs
+++ b/ctr-std/src/sync/once.rs
@@ -72,9 +72,11 @@ use thread::{self, Thread};
/// A synchronization primitive which can be used to run a one-time global
/// initialization. Useful for one-time initialization for FFI or related
-/// functionality. This type can only be constructed with the `ONCE_INIT`
+/// functionality. This type can only be constructed with the [`ONCE_INIT`]
/// value.
///
+/// [`ONCE_INIT`]: constant.ONCE_INIT.html
+///
/// # Examples
///
/// ```
@@ -101,15 +103,28 @@ unsafe impl Sync for Once {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl Send for Once {}
-/// State yielded to the `call_once_force` method which can be used to query
-/// whether the `Once` was previously poisoned or not.
+/// State yielded to [`call_once_force`]’s closure parameter. The state can be
+/// used to query the poison status of the [`Once`].
+///
+/// [`call_once_force`]: struct.Once.html#method.call_once_force
+/// [`Once`]: struct.Once.html
#[unstable(feature = "once_poison", issue = "33577")]
#[derive(Debug)]
pub struct OnceState {
poisoned: bool,
}
-/// Initialization value for static `Once` values.
+/// Initialization value for static [`Once`] values.
+///
+/// [`Once`]: struct.Once.html
+///
+/// # Examples
+///
+/// ```
+/// use std::sync::{Once, ONCE_INIT};
+///
+/// static START: Once = ONCE_INIT;
+/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub const ONCE_INIT: Once = Once::new();
@@ -212,15 +227,52 @@ impl Once {
self.call_inner(false, &mut |_| f.take().unwrap()());
}
- /// Performs the same function as `call_once` except ignores poisoning.
+ /// Performs the same function as [`call_once`] except ignores poisoning.
+ ///
+ /// Unlike [`call_once`], if this `Once` has been poisoned (i.e. a previous
+ /// call to `call_once` or `call_once_force` caused a panic), calling
+ /// `call_once_force` will still invoke the closure `f` and will _not_
+ /// result in an immediate panic. If `f` panics, the `Once` will remain
+ /// in a poison state. If `f` does _not_ panic, the `Once` will no
+ /// longer be in a poison state and all future calls to `call_once` or
+ /// `call_one_force` will no-op.
+ ///
+ /// The closure `f` is yielded a [`OnceState`] structure which can be used
+ /// to query the poison status of the `Once`.
+ ///
+ /// [`call_once`]: struct.Once.html#method.call_once
+ /// [`OnceState`]: struct.OnceState.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(once_poison)]
+ ///
+ /// use std::sync::{Once, ONCE_INIT};
+ /// use std::thread;
+ ///
+ /// static INIT: Once = ONCE_INIT;
+ ///
+ /// // poison the once
+ /// let handle = thread::spawn(|| {
+ /// INIT.call_once(|| panic!());
+ /// });
+ /// assert!(handle.join().is_err());
///
- /// If this `Once` has been poisoned (some initialization panicked) then
- /// this function will continue to attempt to call initialization functions
- /// until one of them doesn't panic.
+ /// // poisoning propagates
+ /// let handle = thread::spawn(|| {
+ /// INIT.call_once(|| {});
+ /// });
+ /// assert!(handle.join().is_err());
///
- /// The closure `f` is yielded a structure which can be used to query the
- /// state of this `Once` (whether initialization has previously panicked or
- /// not).
+ /// // call_once_force will still run and reset the poisoned state
+ /// INIT.call_once_force(|state| {
+ /// assert!(state.poisoned());
+ /// });
+ ///
+ /// // once any success happens, we stop propagating the poison
+ /// INIT.call_once(|| {});
+ /// ```
#[unstable(feature = "once_poison", issue = "33577")]
pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
// same as above, just with a different parameter to `call_inner`.
@@ -366,10 +418,47 @@ impl Drop for Finish {
}
impl OnceState {
- /// Returns whether the associated `Once` has been poisoned.
+ /// Returns whether the associated [`Once`] was poisoned prior to the
+ /// invocation of the closure passed to [`call_once_force`].
+ ///
+ /// [`call_once_force`]: struct.Once.html#method.call_once_force
+ /// [`Once`]: struct.Once.html
+ ///
+ /// # Examples
+ ///
+ /// A poisoned `Once`:
+ ///
+ /// ```
+ /// #![feature(once_poison)]
+ ///
+ /// use std::sync::{Once, ONCE_INIT};
+ /// use std::thread;
+ ///
+ /// static INIT: Once = ONCE_INIT;
+ ///
+ /// // poison the once
+ /// let handle = thread::spawn(|| {
+ /// INIT.call_once(|| panic!());
+ /// });
+ /// assert!(handle.join().is_err());
+ ///
+ /// INIT.call_once_force(|state| {
+ /// assert!(state.poisoned());
+ /// });
+ /// ```
+ ///
+ /// An unpoisoned `Once`:
+ ///
+ /// ```
+ /// #![feature(once_poison)]
+ ///
+ /// use std::sync::{Once, ONCE_INIT};
+ ///
+ /// static INIT: Once = ONCE_INIT;
///
- /// Once an initalization routine for a `Once` has panicked it will forever
- /// indicate to future forced initialization routines that it is poisoned.
+ /// INIT.call_once_force(|state| {
+ /// assert!(!state.poisoned());
+ /// });
#[unstable(feature = "once_poison", issue = "33577")]
pub fn poisoned(&self) -> bool {
self.poisoned