]> Cypherpunks.ru repositories - goredo.git/commitdiff
Acquire jobserver's token prior to opening the lockfile
authorSergey Matveev <stargrave@stargrave.org>
Sun, 8 May 2022 11:09:36 +0000 (14:09 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 8 May 2022 11:09:36 +0000 (14:09 +0300)
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
run.go
usage.go

index cce9c20ce0696182b3137b902421abaaa17a93c9..856e1865f1d24e61bb0495bfaba7fb400301c87c 100644 (file)
@@ -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 c0d6eda2fd0f31920d13034e28592fa05ace013c..44d25d55045943eafcc873831444915ae458b404 100644 (file)
--- 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 {
index 2c9b1a0fe0b1201beb06c9ae7ed1013e44207904..f5340640aba1d56f4e4d719854965ed69051181e 100644 (file)
--- 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