Skip to content

Commit

Permalink
Release a jobserver token while locking a file
Browse files Browse the repository at this point in the history
This is intended to fix #6747 where multiple Cargos invoked with the
same jobserver would all have their own token but not actually run
concurrently due to file locking. Instead the fix is that whenever Cargo
blocks for a file lock with a configured global jobserver, a token is
released just before we block and then reacquired afterwards. This way
we should ensure that we're not hogging a cpu/token unnecessarily
without doing any work!

Closes #6747
  • Loading branch information
alexcrichton committed Mar 15, 2019
1 parent 9eeece1 commit d19b41f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 21 additions & 2 deletions src/cargo/util/flock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit d19b41f

Please sign in to comment.