Skip to content

Commit 58aa9c5

Browse files
committed
fix disk cache datarace
1 parent a389ff1 commit 58aa9c5

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

src/cache/disk.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,26 @@ pub fn get<T: Serialize + DeserializeOwned, P: Serialize>(
4949

5050
// Store the params.json if it doesn't exist for better debuggability
5151
let params_path = cache_dir.join("params.json");
52-
if !params_path.try_exists()? {
53-
// First write the file to .tmp and then rename to avoid a corrupted file if we crash in
54-
// the middle of the write.
55-
let params_path_tmp = cache_dir.join("params.json.tmp");
56-
let mut file = File::create(&params_path_tmp)?;
57-
file.write_all(params_json.as_bytes())?;
58-
rename(params_path_tmp, params_path)?;
52+
loop {
53+
if !params_path.try_exists()? {
54+
// First write the file to .tmp and then rename to avoid having a corrupted file if we
55+
// crash in the middle of the write.
56+
let params_path_tmp = cache_dir.join("params.json.tmp");
57+
let mut file = File::create(&params_path_tmp)?;
58+
match file.try_lock() {
59+
Ok(_) => (),
60+
Err(TryLockError::WouldBlock) => {
61+
// Lock not acquired. Another process is storing the params, let's
62+
// try again in 100 ms.
63+
thread::sleep(time::Duration::from_millis(100));
64+
continue;
65+
}
66+
Err(TryLockError::Error(err)) => return Err(Box::new(err)),
67+
}
68+
file.write_all(params_json.as_bytes())?;
69+
rename(params_path_tmp, params_path)?;
70+
}
71+
break;
5972
}
6073

6174
let cache_path = cache_dir.join(format!("{}.cbor", name));

0 commit comments

Comments
 (0)