Skip to content

Commit cc92493

Browse files
committed
bootstrap: Switch from fd-lock to native locking in std
In the process, fix a race condition, by never truncating or writing to the file unless we currently hold the lock.
1 parent 898aff7 commit cc92493

File tree

3 files changed

+21
-38
lines changed

3 files changed

+21
-38
lines changed

src/bootstrap/Cargo.lock

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ dependencies = [
5050
"clap",
5151
"clap_complete",
5252
"cmake",
53-
"fd-lock",
5453
"home",
5554
"ignore",
5655
"insta",
@@ -262,17 +261,6 @@ version = "2.3.0"
262261
source = "registry+https://github.com/rust-lang/crates.io-index"
263262
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
264263

265-
[[package]]
266-
name = "fd-lock"
267-
version = "4.0.4"
268-
source = "registry+https://github.com/rust-lang/crates.io-index"
269-
checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78"
270-
dependencies = [
271-
"cfg-if",
272-
"rustix",
273-
"windows-sys 0.59.0",
274-
]
275-
276264
[[package]]
277265
name = "filetime"
278266
version = "0.2.25"

src/bootstrap/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ cmake = "=0.1.54"
3838
build_helper = { path = "../build_helper" }
3939
clap = { version = "4.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] }
4040
clap_complete = "4.4"
41-
fd-lock = "4.0"
4241
home = "0.5"
4342
ignore = "0.4"
4443
libc = "0.2"

src/bootstrap/src/bin/main.rs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
//! parent directory, and otherwise documentation can be found throughout the `build`
66
//! directory in each respective module.
77
8-
use std::fs::{self, OpenOptions};
9-
use std::io::{self, BufRead, BufReader, IsTerminal, Write};
8+
use std::fs::{self, OpenOptions, TryLockError};
9+
use std::io::{self, BufRead, BufReader, IsTerminal, Read, Write};
1010
use std::str::FromStr;
1111
use std::time::Instant;
1212
use std::{env, process};
@@ -41,38 +41,34 @@ fn main() {
4141
let config = Config::parse(flags);
4242

4343
let mut build_lock;
44-
let _build_lock_guard;
4544

4645
if !config.bypass_bootstrap_lock {
4746
// Display PID of process holding the lock
4847
// PID will be stored in a lock file
4948
let lock_path = config.out.join("lock");
50-
let pid = fs::read_to_string(&lock_path);
51-
52-
build_lock = fd_lock::RwLock::new(t!(fs::OpenOptions::new()
49+
build_lock = t!(fs::OpenOptions::new()
50+
.read(true)
5351
.write(true)
54-
.truncate(true)
5552
.create(true)
56-
.open(&lock_path)));
57-
_build_lock_guard = match build_lock.try_write() {
58-
Ok(mut lock) => {
59-
t!(lock.write(process::id().to_string().as_ref()));
60-
lock
53+
.truncate(false)
54+
.open(&lock_path));
55+
t!(build_lock.try_lock().or_else(|e| {
56+
if let TryLockError::Error(e) = e {
57+
return Err(e);
6158
}
62-
err => {
63-
drop(err);
64-
// #135972: We can reach this point when the lock has been taken,
65-
// but the locker has not yet written its PID to the file
66-
if let Some(pid) = pid.ok().filter(|pid| !pid.is_empty()) {
67-
println!("WARNING: build directory locked by process {pid}, waiting for lock");
68-
} else {
69-
println!("WARNING: build directory locked, waiting for lock");
70-
}
71-
let mut lock = t!(build_lock.write());
72-
t!(lock.write(process::id().to_string().as_ref()));
73-
lock
59+
let mut pid = String::new();
60+
t!(build_lock.read_to_string(&mut pid));
61+
// #135972: We can reach this point when the lock has been taken,
62+
// but the locker has not yet written its PID to the file
63+
if !pid.is_empty() {
64+
println!("WARNING: build directory locked by process {pid}, waiting for lock");
65+
} else {
66+
println!("WARNING: build directory locked, waiting for lock");
7467
}
75-
};
68+
build_lock.lock()
69+
}));
70+
t!(build_lock.set_len(0));
71+
t!(build_lock.write_all(process::id().to_string().as_bytes()));
7672
}
7773

7874
// check_version warnings are not printed during setup, or during CI

0 commit comments

Comments
 (0)