Skip to content

Commit 714080e

Browse files
author
Xinye
committed
use once cell to store registry
Signed-off-by: Xinye <[email protected]>
1 parent eb63946 commit 714080e

File tree

1 file changed

+52
-24
lines changed

1 file changed

+52
-24
lines changed

src/lib.rs

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,11 @@ struct FailPointRegistry {
535535
registry: RwLock<Registry>,
536536
}
537537

538-
use once_cell::sync::Lazy;
538+
use once_cell::sync::{Lazy, OnceCell};
539539

540-
static REGISTRY: Lazy<FailPointRegistry> = Lazy::new(FailPointRegistry::default);
541-
static SCENARIO: Lazy<Mutex<&'static FailPointRegistry>> = Lazy::new(|| Mutex::new(&REGISTRY));
540+
static REGISTRY: OnceCell<FailPointRegistry> = OnceCell::new();
541+
static SCENARIO: Lazy<Mutex<&'static FailPointRegistry>> =
542+
Lazy::new(|| Mutex::new(REGISTRY.get_or_init(Default::default)));
542543

543544
/// Test scenario with configured fail points.
544545
#[derive(Debug)]
@@ -636,7 +637,11 @@ pub const fn has_failpoints() -> bool {
636637
///
637638
/// Return a vector of `(name, actions)` pairs.
638639
pub fn list() -> Vec<(String, String)> {
639-
let registry = REGISTRY.registry.read().unwrap();
640+
let registry = if let Some(r) = REGISTRY.get() {
641+
r.registry.read().unwrap()
642+
} else {
643+
return Vec::new();
644+
};
640645
registry
641646
.iter()
642647
.map(|(name, fp)| (name.to_string(), fp.actions_str.read().unwrap().clone()))
@@ -645,8 +650,13 @@ pub fn list() -> Vec<(String, String)> {
645650

646651
#[doc(hidden)]
647652
pub fn eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
653+
let registry = if let Some(r) = REGISTRY.get() {
654+
&r.registry
655+
} else {
656+
return None;
657+
};
648658
let p = {
649-
let registry = REGISTRY.registry.read().unwrap();
659+
let registry = registry.read().unwrap();
650660
match registry.get(name) {
651661
None => return None,
652662
Some(p) => p.clone(),
@@ -686,7 +696,11 @@ pub fn eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
686696
/// A call to `cfg` with a particular fail point name overwrites any existing actions for
687697
/// that fail point, including those set via the `FAILPOINTS` environment variable.
688698
pub fn cfg<S: Into<String>>(name: S, actions: &str) -> Result<(), String> {
689-
let mut registry = REGISTRY.registry.write().unwrap();
699+
let mut registry = REGISTRY
700+
.get_or_init(Default::default)
701+
.registry
702+
.write()
703+
.unwrap();
690704
set(&mut registry, name.into(), actions)
691705
}
692706

@@ -699,7 +713,11 @@ where
699713
S: Into<String>,
700714
F: Fn() + Send + Sync + 'static,
701715
{
702-
let mut registry = REGISTRY.registry.write().unwrap();
716+
let mut registry = REGISTRY
717+
.get_or_init(Default::default)
718+
.registry
719+
.write()
720+
.unwrap();
703721
let p = registry
704722
.entry(name.into())
705723
.or_insert_with(|| Arc::new(FailPoint::new()));
@@ -713,7 +731,11 @@ where
713731
///
714732
/// If the fail point doesn't exist, nothing will happen.
715733
pub fn remove<S: AsRef<str>>(name: S) {
716-
let mut registry = REGISTRY.registry.write().unwrap();
734+
let mut registry = if let Some(r) = REGISTRY.get() {
735+
r.registry.write().unwrap()
736+
} else {
737+
return;
738+
};
717739
if let Some(p) = registry.remove(name.as_ref()) {
718740
// wake up all pause failpoint.
719741
p.set_actions("", vec![]);
@@ -937,7 +959,11 @@ mod async_imp {
937959
S: Into<String>,
938960
F: Fn() -> BoxFuture<'static, ()> + Send + Sync + 'static,
939961
{
940-
let mut registry = REGISTRY.registry.write().unwrap();
962+
let mut registry = REGISTRY
963+
.get_or_init(Default::default)
964+
.registry
965+
.write()
966+
.unwrap();
941967
let p = registry
942968
.entry(name.into())
943969
.or_insert_with(|| Arc::new(FailPoint::new()));
@@ -949,8 +975,13 @@ mod async_imp {
949975

950976
#[doc(hidden)]
951977
pub async fn async_eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
978+
let registry = if let Some(r) = REGISTRY.get() {
979+
&r.registry
980+
} else {
981+
return None;
982+
};
952983
let p = {
953-
let registry = REGISTRY.registry.read().unwrap();
984+
let registry = registry.read().unwrap();
954985
match registry.get(name) {
955986
None => return None,
956987
Some(p) => p.clone(),
@@ -985,7 +1016,6 @@ mod async_imp {
9851016
.next();
9861017
match task {
9871018
Some(Task::Pause) => {
988-
// let n = self.async_pause_notify.clone();
9891019
self.async_pause_notify.notified().await;
9901020
return None;
9911021
}
@@ -1017,7 +1047,7 @@ mod async_imp {
10171047
},
10181048
Task::Pause => unreachable!(),
10191049
Task::Yield => thread::yield_now(),
1020-
Task::Delay(_) => {
1050+
Task::Delay(t) => {
10211051
let timer = Instant::now();
10221052
let timeout = Duration::from_millis(t);
10231053
while timer.elapsed() < timeout {}
@@ -1251,21 +1281,19 @@ mod tests {
12511281
#[cfg(feature = "async")]
12521282
#[cfg_attr(not(feature = "failpoints"), ignore)]
12531283
#[tokio::test]
1254-
async fn test_async_failpoint() {
1255-
use std::time::Duration;
1256-
1284+
async fn test_async_failpoints() {
12571285
let f1 = async {
1258-
async_fail_point!("cb");
1286+
async_fail_point!("async_cb");
12591287
};
12601288
let f2 = async {
1261-
async_fail_point!("cb");
1289+
async_fail_point!("async_cb");
12621290
};
12631291

12641292
let counter = Arc::new(AtomicUsize::new(0));
12651293
let counter2 = counter.clone();
1266-
cfg_async_callback("cb", move || {
1294+
cfg_async_callback("async_cb", move || {
12671295
counter2.fetch_add(1, Ordering::SeqCst);
1268-
Box::pin(async move {
1296+
Box::pin(async {
12691297
tokio::time::sleep(Duration::from_millis(10)).await;
12701298
})
12711299
})
@@ -1274,26 +1302,26 @@ mod tests {
12741302
f2.await;
12751303
assert_eq!(2, counter.load(Ordering::SeqCst));
12761304

1277-
cfg("pause", "pause").unwrap();
1305+
cfg("async_pause", "pause").unwrap();
12781306
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
12791307
let handle = tokio::spawn(async move {
1280-
async_fail_point!("pause");
1308+
async_fail_point!("async_pause");
12811309
tx.send(()).await.unwrap();
12821310
});
12831311
tokio::time::timeout(Duration::from_millis(500), rx.recv())
12841312
.await
12851313
.unwrap_err();
1286-
remove("pause");
1314+
remove("async_pause");
12871315
tokio::time::timeout(Duration::from_millis(500), rx.recv())
12881316
.await
12891317
.unwrap();
12901318
handle.await.unwrap();
12911319

1292-
cfg("sleep", "sleep(500)").unwrap();
1320+
cfg("async_sleep", "sleep(500)").unwrap();
12931321
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
12941322
let handle = tokio::spawn(async move {
12951323
tx.send(()).await.unwrap();
1296-
async_fail_point!("sleep");
1324+
async_fail_point!("async_sleep");
12971325
tx.send(()).await.unwrap();
12981326
});
12991327
rx.recv().await.unwrap();

0 commit comments

Comments
 (0)