Skip to content

Commit d19b41f

Browse files
committed
Release a jobserver token while locking a file
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
1 parent 9eeece1 commit d19b41f

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ hex = "0.3"
3939
home = "0.3"
4040
ignore = "0.4"
4141
lazy_static = "1.2.0"
42-
jobserver = "0.1.11"
42+
jobserver = "0.1.13"
4343
lazycell = "1.2.0"
4444
libc = "0.2"
4545
log = "0.4.6"

src/cargo/util/flock.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,27 @@ fn acquire(
312312
let msg = format!("waiting for file lock on {}", msg);
313313
config.shell().status_with_color("Blocking", &msg, Cyan)?;
314314

315-
block().chain_err(|| format!("failed to lock file: {}", path.display()))?;
316-
return Ok(());
315+
// We're about to block the current process and not really do anything
316+
// productive for what could possibly be a very long time. We could be
317+
// waiting, for example, on another Cargo to finish a download, finish an
318+
// entire build, etc. Since we're not doing anything productive we're not
319+
// making good use of our jobserver token, if we have one.
320+
//
321+
// This can typically come about if `cargo` is invoked from `make` (or some
322+
// other jobserver-providing system). In this situation it's actually best
323+
// if we release the token back to the original jobserver to let some other
324+
// cpu-hungry work continue to make progress. After we're done blocking
325+
// we'll block waiting to reacquire a token as we'll probably be doing cpu
326+
// hungry work ourselves.
327+
let jobserver = config.jobserver_from_env();
328+
if let Some(server) = jobserver {
329+
server.release_raw()?;
330+
}
331+
let result = block().chain_err(|| format!("failed to lock file: {}", path.display()));
332+
if let Some(server) = jobserver {
333+
server.acquire_raw()?;
334+
}
335+
return Ok(result?);
317336

318337
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
319338
fn is_on_nfs_mount(path: &Path) -> bool {

0 commit comments

Comments
 (0)