hgcommands: avoid deadlock setting up fail points in different threads

Summary:
It turns out that D30052693 (fd10938296) was not enough. The FailScenario cannot be setup
from different threads too.  Doing that would cause deadlock. So let's avoid
that too.

Reviewed By: DurhamG

Differential Revision: D30124930

fbshipit-source-id: 0095bcf5ad3a99831d9b9c75a1e9f2c50729819b
This commit is contained in:
Jun Wu 2021-08-05 10:00:07 -07:00 committed by Facebook GitHub Bot
parent fe1728f79b
commit 607be999e1

View File

@ -19,7 +19,6 @@ use hg_http::HgHttpConfig;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use parking_lot::Mutex; use parking_lot::Mutex;
use progress_model::Registry; use progress_model::Registry;
use std::cell::Cell;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
@ -27,6 +26,7 @@ use std::io::{BufWriter, Write};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
use std::sync::Arc; use std::sync::Arc;
use std::sync::Weak; use std::sync::Weak;
use std::thread; use std::thread;
@ -174,6 +174,7 @@ pub fn run_command(args: Vec<String>, io: &IO) -> i32 {
if let Some(scenario) = scenario { if let Some(scenario) = scenario {
scenario.teardown(); scenario.teardown();
FAIL_SETUP.store(false, SeqCst);
} }
exit_code exit_code
@ -572,18 +573,17 @@ fn setup_eager_repo() {
*REGISTERED *REGISTERED
} }
thread_local! { static FAIL_SETUP: AtomicBool = AtomicBool::new(false);
static FAIL_SETUP: Cell<bool> = Cell::new(false);
}
fn setup_fail_points<'a>() -> Option<FailScenario<'a>> { fn setup_fail_points<'a>() -> Option<FailScenario<'a>> {
FAIL_SETUP.with(|b| { if std::env::var("FAILPOINTS").is_err() {
if b.get() { // No need to setup failpoints.
// Already setup. return None;
None }
} else { if FAIL_SETUP.fetch_or(true, SeqCst) {
b.set(true); // Already setup.
Some(FailScenario::setup()) None
} } else {
}) Some(FailScenario::setup())
}
} }