]> Cypherpunks.ru repositories - goredo.git/commitdiff
Prevent possible race when building target twice
authorSergey Matveev <stargrave@stargrave.org>
Sat, 23 Sep 2023 14:13:59 +0000 (17:13 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 23 Sep 2023 18:31:20 +0000 (21:31 +0300)
doc/news.texi
ifchange.go
main.go
run.go
usage.go

index d519c7d3d3443673fe08b6a4c7769f8fc61b2617..fcd0d75e1ad4a15e37c572d23c65f4d90d883f57 100644 (file)
@@ -2,6 +2,13 @@
 @cindex news
 @unnumbered News
 
+@anchor{Release 1_31_0}
+@section Release 1.31.0
+@itemize
+@item
+    Fixed possible race when target can be built more than once.
+@end itemize
+
 @anchor{Release 1_30_0}
 @section Release 1.30.0
 @itemize
index 4a43872c2cf35b4ec4a8ae0a97739f6b0de5bb1b..401574de816b8ef06d7af2c2210917326823807d 100644 (file)
@@ -109,7 +109,7 @@ func buildDependants(tgts []string) map[string]struct{} {
        tracef(CDebug, "building %d alwayses: %v", len(seen), seen)
        errs := make(chan error, len(seen))
        for tgt := range seen {
-               if err := runScript(tgt, errs, false); err != nil {
+               if err := runScript(tgt, errs, false, false); err != nil {
                        tracef(CErr, "always run error: %s, skipping dependants", err)
                        return nil
                }
@@ -155,7 +155,7 @@ RebuildDeps:
                if !ood {
                        continue
                }
-               if err := runScript(tgt, errs, false); err != nil {
+               if err := runScript(tgt, errs, false, false); err != nil {
                        tracef(CErr, "dependant error: %s, skipping dependants", err)
                        return nil
                }
@@ -225,7 +225,7 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) {
                        tracef(CDebug, "%s is source, not redoing", tgt)
                        continue
                }
-               if err = runScript(tgt, errs, traced); err != nil {
+               if err = runScript(tgt, errs, forced, traced); err != nil {
                        return false, err
                }
                jobs++
diff --git a/main.go b/main.go
index 634ca8fdff584f78140f35f4db8d178c58894d69..8c95d84bd3ed76135ce08086ebb595498b8635e0 100644 (file)
--- a/main.go
+++ b/main.go
@@ -298,7 +298,7 @@ func main() {
                }
        }
 
-       if cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange {
+       if cmdName == CmdNameRedo {
                statusInit()
        }
 
diff --git a/run.go b/run.go
index 2e5dbf5f7ebd5fc8e9c4cfc6e8194333b0456fd9..7ee463714ed229448325014944d91c9fab266d18 100644 (file)
--- a/run.go
+++ b/run.go
@@ -184,7 +184,7 @@ func syncDir(dir string) error {
        return err
 }
 
-func runScript(tgtOrig string, errs chan error, traced bool) error {
+func runScript(tgtOrig string, errs chan error, forced, traced bool) error {
        cwd, tgt := cwdAndTgt(tgtOrig)
        redoDir := path.Join(cwd, RedoDir)
        if err := mkdirs(redoDir); err != nil {
@@ -281,6 +281,19 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                return nil
        }
 
+       // Check if it was already built in parallel
+       if !forced {
+               if fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)); err == nil {
+                       depInfo, err := depRead(fdDep)
+                       fdDep.Close()
+                       if err == nil && depInfo.build == BuildUUID {
+                               lockRelease()
+                               errs <- nil
+                               return nil
+                       }
+               }
+       }
+
        // Check if target is not modified externally
        modified, inodePrev, hshPrev, err := isModified(cwd, redoDir, tgt)
        if err != nil {
index e67077fdfd40c6a8c5bab6e376ed9301c92fd17f..6e43b57e832b4c929b5792c2f7fea448bbe0af7a 100644 (file)
--- a/usage.go
+++ b/usage.go
@@ -24,7 +24,7 @@ import (
 )
 
 const (
-       Version  = "1.30.0"
+       Version  = "1.31.0"
        Warranty = `Copyright (C) 2020-2023 Sergey Matveev
 
 This program is free software: you can redistribute it and/or modify