@@ -229,7 +229,7 @@ use std::collections::HashMap;
229
229
use std:: env:: VarError ;
230
230
use std:: fmt:: Debug ;
231
231
use std:: str:: FromStr ;
232
- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
232
+ use std:: sync:: atomic:: { AtomicBool , AtomicUsize , Ordering } ;
233
233
use std:: sync:: { Arc , Condvar , Mutex , MutexGuard , RwLock , TryLockError } ;
234
234
use std:: time:: { Duration , Instant } ;
235
235
use std:: { env, thread} ;
@@ -528,6 +528,9 @@ use once_cell::sync::Lazy;
528
528
static REGISTRY : Lazy < FailPointRegistry > = Lazy :: new ( FailPointRegistry :: default) ;
529
529
static SCENARIO : Lazy < Mutex < & ' static FailPointRegistry > > = Lazy :: new ( || Mutex :: new ( & REGISTRY ) ) ;
530
530
531
+ #[ doc( hidden) ]
532
+ pub static REGISTRY_IS_EMPTY : AtomicBool = AtomicBool :: new ( true ) ;
533
+
531
534
/// Test scenario with configured fail points.
532
535
#[ derive( Debug ) ]
533
536
pub struct FailScenario < ' a > {
@@ -580,6 +583,7 @@ impl<'a> FailScenario<'a> {
580
583
}
581
584
}
582
585
}
586
+ update_registry_is_empty ( & registry) ;
583
587
Self { scenario_guard }
584
588
}
585
589
@@ -601,6 +605,7 @@ impl<'a> FailScenario<'a> {
601
605
p. set_actions ( "" , vec ! [ ] ) ;
602
606
}
603
607
registry. clear ( ) ;
608
+ update_registry_is_empty ( registry) ;
604
609
}
605
610
}
606
611
@@ -675,7 +680,9 @@ pub fn eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
675
680
/// that fail point, including those set via the `FAILPOINTS` environment variable.
676
681
pub fn cfg < S : Into < String > > ( name : S , actions : & str ) -> Result < ( ) , String > {
677
682
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 ( ( ) )
679
686
}
680
687
681
688
/// Configure the actions for a fail point at runtime.
@@ -694,6 +701,7 @@ where
694
701
let action = Action :: from_callback ( f) ;
695
702
let actions = vec ! [ action] ;
696
703
p. set_actions ( "callback" , actions) ;
704
+ update_registry_is_empty ( & registry) ;
697
705
Ok ( ( ) )
698
706
}
699
707
@@ -762,6 +770,10 @@ fn set(
762
770
Ok ( ( ) )
763
771
}
764
772
773
+ fn update_registry_is_empty ( registry : & HashMap < String , Arc < FailPoint > > ) {
774
+ REGISTRY_IS_EMPTY . store ( registry. is_empty ( ) , Ordering :: Release ) ;
775
+ }
776
+
765
777
/// Define a fail point (requires `failpoints` feature).
766
778
///
767
779
/// The `fail_point!` macro has three forms, and they all take a name as the
@@ -827,13 +839,17 @@ fn set(
827
839
#[ cfg( feature = "failpoints" ) ]
828
840
macro_rules! fail_point {
829
841
( $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
+ }
833
847
} } ;
834
848
( $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
+ }
837
853
}
838
854
} } ;
839
855
( $name: expr, $cond: expr, $e: expr) => { {
0 commit comments