From 906d2d0d72e16bbdb17653b834a980f134309a59 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 8 May 2022 14:09:36 +0300 Subject: [PATCH] Acquire jobserver's token prior to opening the lockfile Previously goredo opened corresponding lockfiles for each target simultaneously, leading to many opened file descriptors. Now it takes a jobserver's token before that, so number of opened lockfiles correlates with the jobserver's slots. One of the drawbacks is that we wait and take the jobserver's token even if target was actually already done before. --- doc/news.texi | 9 +++++++++ run.go | 22 ++++++++++++++++------ usage.go | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/doc/news.texi b/doc/news.texi index cce9c20..856e186 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -2,6 +2,15 @@ @cindex news @unnumbered News +@anchor{Release 1_25_0} +@section Release 1.25.0 +@itemize +@item + Target's lock file requires a token from the jobserver now. So + amount of simultaneously opened lock files depends on job slots + available. +@end itemize + @anchor{Release 1_24_0} @section Release 1.24.0 @itemize diff --git a/run.go b/run.go index c0d6eda..44d25d5 100644 --- a/run.go +++ b/run.go @@ -194,6 +194,15 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { return TgtError{tgtOrig, err} } + shCtx := fmt.Sprintf("sh: %s: cwd:%s", tgtOrig, cwd) + jsToken := jsAcquire(shCtx) + jsNeedsRelease := true + defer func() { + if jsNeedsRelease { + jsRelease(shCtx, jsToken) + } + }() + // Acquire lock fdLock, err := os.OpenFile( path.Join(redoDir, tgt+LockSuffix), @@ -381,6 +390,10 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { path.Join(dirPrefix, basename), tmpPathRel, ) + shCtx = fmt.Sprintf( + "sh: %s: %s %s cwd:%s dirprefix:%s", + tgtOrig, cmdName, args, cwd, dirPrefix, + ) cmd := exec.Command(cmdName, args...) cmd.Dir = cwd @@ -423,15 +436,11 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { return TgtError{tgtOrig, err} } } - shCtx := fmt.Sprintf( - "sh: %s: %s %s cwd:%s dirprefix:%s", - tgtOrig, cmdName, args, cwd, dirPrefix, - ) tracef(CDebug, "%s", shCtx) + jsNeedsRelease = false Jobs.Add(1) go func() { - jsToken := jsAcquire(shCtx) if JSR == nil { // infinite jobs cmd.Env = append(cmd.Env, fmt.Sprintf("%s=NO", EnvJobs)) @@ -453,6 +462,8 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } } + defer jsRelease(shCtx, jsToken) + var finished time.Time var exitErr *exec.ExitError started := time.Now() @@ -483,7 +494,6 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDepCwd, cwd)) defer func() { - jsRelease(shCtx, jsToken) fdDep.Close() fdStdout.Close() if fdStderr != nil { diff --git a/usage.go b/usage.go index 2c9b1a0..f534064 100644 --- a/usage.go +++ b/usage.go @@ -24,7 +24,7 @@ import ( ) const ( - Version = "1.24.0" + Version = "1.25.0" Warranty = `Copyright (C) 2020-2022 Sergey Matveev This program is free software: you can redistribute it and/or modify -- 2.44.0