}
}
}
-
-// Like std::fs::create_dir_all, except handles concurrent calls among multiple
-// threads or processes.
-pub fn create_dir_racy(path: &Path) -> io::Result<()> {
- match fs::create_dir(path) {
- Ok(()) => return Ok(()),
- Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return Ok(()),
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => (),
- Err(e) => return Err(e),
- }
- match path.parent() {
- Some(p) => try!(create_dir_racy(p)),
- None => return Err(io::Error::new(io::ErrorKind::Other, "failed to create whole tree")),
- }
- match fs::create_dir(path) {
- Ok(()) => Ok(()),
- Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()),
- Err(e) => Err(e),
- }
-}
/// error conditions for when a directory is being created (after it is
/// determined to not exist) are outlined by `fs::create_dir`.
///
+/// Notable exception is made for situations where any of the directories
+/// specified in the `path` could not be created as it was created concurrently.
+/// Such cases are considered success. In other words: calling `create_dir_all`
+/// concurrently from multiple threads or processes is guaranteed to not fail
+/// due to race itself.
+///
/// # Examples
///
/// ```
}
fn create_dir_all(&self, path: &Path) -> io::Result<()> {
- if path == Path::new("") || path.is_dir() { return Ok(()) }
- if let Some(p) = path.parent() {
- self.create_dir_all(p)?
+ match self.inner.mkdir(path) {
+ Ok(()) => return Ok(()),
+ Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return Ok(()),
+ Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
+ Err(e) => return Err(e),
+ }
+ match path.parent() {
+ Some(p) => try!(create_dir_all(p)),
+ None => return Err(io::Error::new(io::ErrorKind::Other, "failed to create whole tree")),
+ }
+ match self.inner.mkdir(path) {
+ Ok(()) => Ok(()),
+ Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()),
+ Err(e) => Err(e),
}
- self.inner.mkdir(path)
}
}
use std::collections::HashSet;
use std::env;
use std::fmt;
-use std::fs::{self, File};
+use std::fs::{self, File, create_dir_all};
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::{Path, PathBuf};
let out_dir = self.output_base_name().with_extension("pretty-out");
let _ = fs::remove_dir_all(&out_dir);
- self.create_dir_racy(&out_dir);
+ create_dir_all(&out_dir).unwrap();
// FIXME (#9639): This needs to handle non-utf8 paths
let mut args = vec!["-".to_owned(),
fn compose_and_run_compiler(&self, args: ProcArgs, input: Option<String>) -> ProcRes {
if !self.props.aux_builds.is_empty() {
- self.create_dir_racy(&self.aux_output_dir_name());
+ create_dir_all(&self.aux_output_dir_name()).unwrap();
}
let aux_dir = self.aux_output_dir_name();
input)
}
- // Like std::fs::create_dir_all, except handles concurrent calls among multiple
- // threads or processes.
- fn create_dir_racy(&self, path: &Path) {
- match fs::create_dir(path) {
- Ok(()) => return,
- Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return,
- Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
- Err(e) => panic!("failed to create dir {:?}: {}", path, e),
- }
- self.create_dir_racy(path.parent().unwrap());
- match fs::create_dir(path) {
- Ok(()) => {}
- Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {}
- Err(e) => panic!("failed to create dir {:?}: {}", path, e),
- }
- }
fn compose_and_run(&self,
ProcArgs{ args, prog }: ProcArgs,
let mir_dump_dir = self.get_mir_dump_dir();
- self.create_dir_racy(mir_dump_dir.as_path());
+ create_dir_all(mir_dump_dir.as_path()).unwrap();
let mut dir_opt = "dump-mir-dir=".to_string();
dir_opt.push_str(mir_dump_dir.to_str().unwrap());
debug!("dir_opt: {:?}", dir_opt);
let out_dir = self.output_base_name();
let _ = fs::remove_dir_all(&out_dir);
- self.create_dir_racy(&out_dir);
+ create_dir_all(&out_dir).unwrap();
let proc_res = self.document(&out_dir);
if !proc_res.status.success() {
if tmpdir.exists() {
self.aggressive_rm_rf(&tmpdir).unwrap();
}
- self.create_dir_racy(&tmpdir);
+ create_dir_all(&tmpdir).unwrap();
let host = &self.config.host;
let make = if host.contains("bitrig") || host.contains("dragonfly") ||