From 36d9ee3da983a318f958077dbc68ba1adfae98b8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 24 Apr 2016 21:37:22 -0700 Subject: [PATCH] rustdoc: Handle concurrent mkdir requests It's likely that `rustdoc` as a tool is run concurrently in the same output (e.g. documenting multiple crates as Cargo does), in which case it needs to handle concurrent calls to `fs::create_dir`. --- src/librustdoc/html/render.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 824265bc3b3..c379079054f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -820,13 +820,16 @@ fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> { Ok(try_err!(try_err!(File::create(&dst), &dst).write_all(contents), &dst)) } -/// Makes a directory on the filesystem, failing the thread if an error occurs and -/// skipping if the directory already exists. +/// Makes a directory on the filesystem, failing the thread if an error occurs +/// and skipping if the directory already exists. +/// +/// Note that this also handles races as rustdoc is likely to be run +/// concurrently against another invocation. fn mkdir(path: &Path) -> io::Result<()> { - if !path.exists() { - fs::create_dir(path) - } else { - Ok(()) + match fs::create_dir(path) { + Ok(()) => Ok(()), + Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()), + Err(e) => Err(e) } }