@@ -229,7 +229,7 @@ use std::collections::HashMap;
229229use std:: env:: VarError ;
230230use std:: fmt:: Debug ;
231231use std:: str:: FromStr ;
232- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
232+ use std:: sync:: atomic:: { AtomicBool , AtomicUsize , Ordering } ;
233233use std:: sync:: { Arc , Condvar , Mutex , MutexGuard , RwLock , TryLockError } ;
234234use std:: time:: { Duration , Instant } ;
235235use std:: { env, thread} ;
@@ -528,6 +528,9 @@ use once_cell::sync::Lazy;
528528static REGISTRY : Lazy < FailPointRegistry > = Lazy :: new ( FailPointRegistry :: default) ;
529529static SCENARIO : Lazy < Mutex < & ' static FailPointRegistry > > = Lazy :: new ( || Mutex :: new ( & REGISTRY ) ) ;
530530
531+ #[ doc( hidden) ]
532+ pub static REGISTRY_IS_EMPTY : AtomicBool = AtomicBool :: new ( true ) ;
533+
531534/// Test scenario with configured fail points.
532535#[ derive( Debug ) ]
533536pub struct FailScenario < ' a > {
@@ -580,6 +583,7 @@ impl<'a> FailScenario<'a> {
580583 }
581584 }
582585 }
586+ update_registry_is_empty ( & registry) ;
583587 Self { scenario_guard }
584588 }
585589
@@ -601,6 +605,7 @@ impl<'a> FailScenario<'a> {
601605 p. set_actions ( "" , vec ! [ ] ) ;
602606 }
603607 registry. clear ( ) ;
608+ update_registry_is_empty ( registry) ;
604609 }
605610}
606611
@@ -675,7 +680,9 @@ pub fn eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
675680/// that fail point, including those set via the `FAILPOINTS` environment variable.
676681pub fn cfg < S : Into < String > > ( name : S , actions : & str ) -> Result < ( ) , String > {
677682 let mut registry = REGISTRY . registry . write ( ) . unwrap ( ) ;
678- set ( & mut registry, name. into ( ) , actions)
683+ set ( & mut registry, name. into ( ) , actions) ?;
684+ update_registry_is_empty ( & registry) ;
685+ Ok ( ( ) )
679686}
680687
681688/// Configure the actions for a fail point at runtime.
@@ -694,6 +701,7 @@ where
694701 let action = Action :: from_callback ( f) ;
695702 let actions = vec ! [ action] ;
696703 p. set_actions ( "callback" , actions) ;
704+ update_registry_is_empty ( & registry) ;
697705 Ok ( ( ) )
698706}
699707
@@ -762,6 +770,10 @@ fn set(
762770 Ok ( ( ) )
763771}
764772
773+ fn update_registry_is_empty ( registry : & HashMap < String , Arc < FailPoint > > ) {
774+ REGISTRY_IS_EMPTY . store ( registry. is_empty ( ) , Ordering :: Release ) ;
775+ }
776+
765777/// Define a fail point (requires `failpoints` feature).
766778///
767779/// The `fail_point!` macro has three forms, and they all take a name as the
@@ -827,13 +839,17 @@ fn set(
827839#[ cfg( feature = "failpoints" ) ]
828840macro_rules! fail_point {
829841 ( $name: expr) => { {
830- $crate:: eval( $name, |_| {
831- panic!( "Return is not supported for the fail point \" {}\" " , $name) ;
832- } ) ;
842+ if !$crate:: REGISTRY_IS_EMPTY . load( :: std:: sync:: atomic:: Ordering :: Acquire ) {
843+ $crate:: eval( $name, |_| {
844+ panic!( "Return is not supported for the fail point \" {}\" " , $name) ;
845+ } ) ;
846+ }
833847 } } ;
834848 ( $name: expr, $e: expr) => { {
835- if let Some ( res) = $crate:: eval( $name, $e) {
836- return res;
849+ if !$crate:: REGISTRY_IS_EMPTY . load( :: std:: sync:: atomic:: Ordering :: Acquire ) {
850+ if let Some ( res) = $crate:: eval( $name, $e) {
851+ return res;
852+ }
837853 }
838854 } } ;
839855 ( $name: expr, $cond: expr, $e: expr) => { {
0 commit comments