Skip to content

Commit 8dc4696

Browse files
committed
Retry deleting a directory
It's possible that a file in the directory is pending deletion. In that case we might succeed after a few attempts.
1 parent 8b1f85c commit 8dc4696

File tree

1 file changed

+15
-2
lines changed
  • library/std/src/sys/windows

1 file changed

+15
-2
lines changed

library/std/src/sys/windows/fs.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,10 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
10181018
}
10191019

10201020
fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
1021+
// When deleting files we may loop this many times when certain error conditions occur.
1022+
// This allows remove_dir_all to succeed when the error is temporary.
1023+
const MAX_RETRIES: u32 = 10;
1024+
10211025
let mut buffer = DirBuff::new();
10221026
let mut dirlist = vec![f.duplicate()?];
10231027

@@ -1040,7 +1044,6 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
10401044
)?;
10411045
dirlist.push(child_dir);
10421046
} else {
1043-
const MAX_RETRIES: u32 = 10;
10441047
for i in 1..=MAX_RETRIES {
10451048
let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
10461049
match result {
@@ -1062,7 +1065,17 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
10621065
// If there were no more files then delete the directory.
10631066
if !more_data {
10641067
if let Some(dir) = dirlist.pop() {
1065-
delete(&dir)?;
1068+
// Retry deleting a few times in case we need to wait for a file to be deleted.
1069+
for i in 1..=MAX_RETRIES {
1070+
let result = delete(&dir);
1071+
if let Err(e) = result {
1072+
if i == MAX_RETRIES || e.kind() != io::ErrorKind::DirectoryNotEmpty {
1073+
return Err(e);
1074+
}
1075+
} else {
1076+
break;
1077+
}
1078+
}
10661079
}
10671080
}
10681081
}

0 commit comments

Comments
 (0)