diff --git a/Cargo.toml b/Cargo.toml index 2c5504421..708bed282 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ hex = "0.3" home = "0.3" ignore = "0.4" lazy_static = "1.2.0" -jobserver = "0.1.11" +jobserver = "0.1.13" lazycell = "1.2.0" libc = "0.2" log = "0.4.6" diff --git a/src/cargo/util/flock.rs b/src/cargo/util/flock.rs index bc87be6c9..e49a4daaa 100644 --- a/src/cargo/util/flock.rs +++ b/src/cargo/util/flock.rs @@ -312,8 +312,27 @@ fn acquire( let msg = format!("waiting for file lock on {}", msg); config.shell().status_with_color("Blocking", &msg, Cyan)?; - block().chain_err(|| format!("failed to lock file: {}", path.display()))?; - return Ok(()); + // We're about to block the current process and not really do anything + // productive for what could possibly be a very long time. We could be + // waiting, for example, on another Cargo to finish a download, finish an + // entire build, etc. Since we're not doing anything productive we're not + // making good use of our jobserver token, if we have one. + // + // This can typically come about if `cargo` is invoked from `make` (or some + // other jobserver-providing system). In this situation it's actually best + // if we release the token back to the original jobserver to let some other + // cpu-hungry work continue to make progress. After we're done blocking + // we'll block waiting to reacquire a token as we'll probably be doing cpu + // hungry work ourselves. + let jobserver = config.jobserver_from_env(); + if let Some(server) = jobserver { + server.release_raw()?; + } + let result = block().chain_err(|| format!("failed to lock file: {}", path.display())); + if let Some(server) = jobserver { + server.acquire_raw()?; + } + return Ok(result?); #[cfg(all(target_os = "linux", not(target_env = "musl")))] fn is_on_nfs_mount(path: &Path) -> bool {