@@ -103,8 +103,8 @@ unsafe impl Sync for Once {}
103103#[ stable( feature = "rust1" , since = "1.0.0" ) ]
104104unsafe impl Send for Once { }
105105
106- /// State yielded to the [`call_once_force`] method which can be used to query
107- /// whether the [`Once`] was previously poisoned or not .
106+ /// State yielded to [`call_once_force`]’s closure parameter. The state can be
107+ /// used to query the poison status of the [`Once`].
108108///
109109/// [`call_once_force`]: struct.Once.html#method.call_once_force
110110/// [`Once`]: struct.Once.html
@@ -230,17 +230,50 @@ impl Once {
230230
231231 /// Performs the same function as [`call_once`] except ignores poisoning.
232232 ///
233+ /// Unlike [`call_once`], if this `Once` has been poisoned (i.e. a previous
234+ /// call to `call_once` or `call_once_force` caused a panic), calling
235+ /// `call_once_force` will still invoke the closure `f` and will _not_
236+ /// result in an immediate panic. If `f` panics, the `Once` will remain
237+ /// in a poison state. If `f` does _not_ panic, the `Once` will no
238+ /// longer be in a poison state and all future calls to `call_once` or
239+ /// `call_one_force` will no-op.
240+ ///
241+ /// The closure `f` is yielded a [`OnceState`] structure which can be used
242+ /// to query the poison status of the `Once`.
243+ ///
233244 /// [`call_once`]: struct.Once.html#method.call_once
245+ /// [`OnceState`]: struct.OnceState.html
234246 ///
235- /// If this `Once` has been poisoned (some initialization panicked) then
236- /// this function will continue to attempt to call initialization functions
237- /// until one of them doesn't panic.
247+ /// # Examples
238248 ///
239- /// The closure `f` is yielded a [`OnceState`] structure which can be used to query the
240- /// state of this `Once` (whether initialization has previously panicked or
241- /// not).
249+ /// ```
250+ /// #![feature(once_poison)]
242251 ///
243- /// [`OnceState`]: struct.OnceState.html
252+ /// use std::sync::{Once, ONCE_INIT};
253+ /// use std::thread;
254+ ///
255+ /// static INIT: Once = ONCE_INIT;
256+ ///
257+ /// // poison the once
258+ /// let handle = thread::spawn(|| {
259+ /// INIT.call_once(|| panic!());
260+ /// });
261+ /// assert!(handle.join().is_err());
262+ ///
263+ /// // poisoning propagates
264+ /// let handle = thread::spawn(|| {
265+ /// INIT.call_once(|| {});
266+ /// });
267+ /// assert!(handle.join().is_err());
268+ ///
269+ /// // call_once_force will still run and reset the poisoned state
270+ /// INIT.call_once_force(|state| {
271+ /// assert!(state.poisoned());
272+ /// });
273+ ///
274+ /// // once any success happens, we stop propagating the poison
275+ /// INIT.call_once(|| {});
276+ /// ```
244277 #[ unstable( feature = "once_poison" , issue = "33577" ) ]
245278 pub fn call_once_force < F > ( & ' static self , f : F ) where F : FnOnce ( & OnceState ) {
246279 // same as above, just with a different parameter to `call_inner`.
@@ -386,12 +419,47 @@ impl Drop for Finish {
386419}
387420
388421impl OnceState {
389- /// Returns whether the associated [`Once`] has been poisoned.
390- ///
391- /// Once an initialization routine for a [`Once`] has panicked it will forever
392- /// indicate to future forced initialization routines that it is poisoned.
422+ /// Returns whether the associated [`Once`] was poisoned prior to the
423+ /// invocation of the closure passed to [`call_once_force`].
393424 ///
425+ /// [`call_once_force`]: struct.Once.html#method.call_once_force
394426 /// [`Once`]: struct.Once.html
427+ ///
428+ /// # Examples
429+ ///
430+ /// A poisoned `Once`:
431+ ///
432+ /// ```
433+ /// #![feature(once_poison)]
434+ ///
435+ /// use std::sync::{Once, ONCE_INIT};
436+ /// use std::thread;
437+ ///
438+ /// static INIT: Once = ONCE_INIT;
439+ ///
440+ /// // poison the once
441+ /// let handle = thread::spawn(|| {
442+ /// INIT.call_once(|| panic!());
443+ /// });
444+ /// assert!(handle.join().is_err());
445+ ///
446+ /// INIT.call_once_force(|state| {
447+ /// assert!(state.poisoned());
448+ /// });
449+ /// ```
450+ ///
451+ /// An unpoisoned `Once`:
452+ ///
453+ /// ```
454+ /// #![feature(once_poison)]
455+ ///
456+ /// use std::sync::{Once, ONCE_INIT};
457+ ///
458+ /// static INIT: Once = ONCE_INIT;
459+ ///
460+ /// INIT.call_once_force(|state| {
461+ /// assert!(!state.poisoned());
462+ /// });
395463 #[ unstable( feature = "once_poison" , issue = "33577" ) ]
396464 pub fn poisoned ( & self ) -> bool {
397465 self . poisoned
0 commit comments