about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-25 19:47:19 +0000
committerbors <bors@rust-lang.org>2022-03-25 19:47:19 +0000
commitd53246fedde4c193eae8a003546a8f0f9f85d223 (patch)
treee1644a87f5e9c66cfeb494f7c0452b23e4f9596b
parent3fe3b89cd57229343eeca753fdd8c63d9b03c65c (diff)
parente5b9430578966c30e37176d25e0b450085359c48 (diff)
downloadrust-d53246fedde4c193eae8a003546a8f0f9f85d223.tar.gz
rust-d53246fedde4c193eae8a003546a8f0f9f85d223.zip
Auto merge of #95304 - michaelwoerister:retry-finalize-session-dir, r=oli-obk
incr. comp.: Let compiler retry finalizing session directory a few times.

In my local testing this fixed issue https://github.com/rust-lang/rust/issues/86929. I wasn't able to come up with a regression test for it though.
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs25
1 files changed, 23 insertions, 2 deletions
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index b13f0b0d3da..9b328842056 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -111,7 +111,7 @@ use rustc_fs_util::{link_or_copy, LinkOrCopy};
 use rustc_session::{Session, StableCrateId};
 
 use std::fs as std_fs;
-use std::io;
+use std::io::{self, ErrorKind};
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
@@ -371,7 +371,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
     let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name);
     debug!("finalize_session_directory() - new path: {}", new_path.display());
 
-    match std_fs::rename(&*incr_comp_session_dir, &new_path) {
+    match rename_path_with_retry(&*incr_comp_session_dir, &new_path, 3) {
         Ok(_) => {
             debug!("finalize_session_directory() - directory renamed successfully");
 
@@ -961,3 +961,24 @@ fn safe_remove_file(p: &Path) -> io::Result<()> {
         result => result,
     }
 }
+
+// On Windows the compiler would sometimes fail to rename the session directory because
+// the OS thought something was still being accessed in it. So we retry a few times to give
+// the OS time to catch up.
+// See https://github.com/rust-lang/rust/issues/86929.
+fn rename_path_with_retry(from: &Path, to: &Path, mut retries_left: usize) -> std::io::Result<()> {
+    loop {
+        match std_fs::rename(from, to) {
+            Ok(()) => return Ok(()),
+            Err(e) => {
+                if retries_left > 0 && e.kind() == ErrorKind::PermissionDenied {
+                    // Try again after a short waiting period.
+                    std::thread::sleep(Duration::from_millis(50));
+                    retries_left -= 1;
+                } else {
+                    return Err(e);
+                }
+            }
+        }
+    }
+}