diff options
| author | Chris Denton <christophersdenton@gmail.com> | 2022-04-26 01:08:46 +0100 |
|---|---|---|
| committer | Chris Denton <christophersdenton@gmail.com> | 2022-04-26 01:08:46 +0100 |
| commit | 8dc4696b3b8e048ddbc4a25953cccb567b27570c (patch) | |
| tree | 7c27f1d9a2284f66d4a1eaded539f25e426541c2 /library/std/src/sys/windows/fs.rs | |
| parent | 8b1f85caede44808e62542cfdff04787d70f8f7f (diff) | |
| download | rust-8dc4696b3b8e048ddbc4a25953cccb567b27570c.tar.gz rust-8dc4696b3b8e048ddbc4a25953cccb567b27570c.zip | |
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.
Diffstat (limited to 'library/std/src/sys/windows/fs.rs')
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 618cbbb1817..e6f0f0f3023 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1018,6 +1018,10 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> { } fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> { + // When deleting files we may loop this many times when certain error conditions occur. + // This allows remove_dir_all to succeed when the error is temporary. + const MAX_RETRIES: u32 = 10; + let mut buffer = DirBuff::new(); let mut dirlist = vec![f.duplicate()?]; @@ -1040,7 +1044,6 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io )?; dirlist.push(child_dir); } else { - const MAX_RETRIES: u32 = 10; for i in 1..=MAX_RETRIES { let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE); match result { @@ -1062,7 +1065,17 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io // If there were no more files then delete the directory. if !more_data { if let Some(dir) = dirlist.pop() { - delete(&dir)?; + // Retry deleting a few times in case we need to wait for a file to be deleted. + for i in 1..=MAX_RETRIES { + let result = delete(&dir); + if let Err(e) = result { + if i == MAX_RETRIES || e.kind() != io::ErrorKind::DirectoryNotEmpty { + return Err(e); + } + } else { + break; + } + } } } } |
