@@ -103,8 +103,8 @@ unsafe impl Sync for Once {}
103
103
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
104
104
unsafe impl Send for Once { }
105
105
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`].
108
108
///
109
109
/// [`call_once_force`]: struct.Once.html#method.call_once_force
110
110
/// [`Once`]: struct.Once.html
@@ -230,17 +230,50 @@ impl Once {
230
230
231
231
/// Performs the same function as [`call_once`] except ignores poisoning.
232
232
///
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
+ ///
233
244
/// [`call_once`]: struct.Once.html#method.call_once
245
+ /// [`OnceState`]: struct.OnceState.html
234
246
///
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
238
248
///
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)]
242
251
///
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
+ /// ```
244
277
#[ unstable( feature = "once_poison" , issue = "33577" ) ]
245
278
pub fn call_once_force < F > ( & ' static self , f : F ) where F : FnOnce ( & OnceState ) {
246
279
// same as above, just with a different parameter to `call_inner`.
@@ -386,12 +419,47 @@ impl Drop for Finish {
386
419
}
387
420
388
421
impl 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`].
393
424
///
425
+ /// [`call_once_force`]: struct.Once.html#method.call_once_force
394
426
/// [`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
+ /// });
395
463
#[ unstable( feature = "once_poison" , issue = "33577" ) ]
396
464
pub fn poisoned ( & self ) -> bool {
397
465
self . poisoned
0 commit comments