aboutsummaryrefslogtreecommitdiffhomepage
path: root/builder/library.go
diff options
context:
space:
mode:
authorNia Waldvogel <[email protected]>2021-12-15 09:39:55 -0500
committerAyke <[email protected]>2021-12-17 09:33:28 +0100
commitd5c0083085f7104b3f0d41290bb2ab4ccc2e5cac (patch)
treef08b5c952e34c827782236a18191abac6b425bde /builder/library.go
parente6fbad13c6caee9ef233ae16a6c95518195f8f70 (diff)
downloadtinygo-d5c0083085f7104b3f0d41290bb2ab4ccc2e5cac.tar.gz
tinygo-d5c0083085f7104b3f0d41290bb2ab4ccc2e5cac.zip
builder: handle concurrent library header rename
When a library is built concurrently by multiple TinyGo processes, they may sometimes both build the headers. In that case a directory rename may fail due to conflict. This change detects and handles the conflict similar to how GOROOT construction does.
Diffstat (limited to 'builder/library.go')
-rw-r--r--builder/library.go19
1 files changed, 18 insertions, 1 deletions
diff --git a/builder/library.go b/builder/library.go
index 730797854..efcc8b75a 100644
--- a/builder/library.go
+++ b/builder/library.go
@@ -4,6 +4,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "runtime"
"strings"
"github.com/tinygo-org/tinygo/compileopts"
@@ -92,7 +93,23 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
}
err = os.Rename(temporaryHeaderPath, headerPath)
if err != nil {
- return nil, err
+ switch {
+ case os.IsExist(err):
+ // Another invocation of TinyGo also seems to have already created the headers.
+
+ case runtime.GOOS == "windows" && os.IsPermission(err):
+ // On Windows, a rename with a destination directory that already
+ // exists does not result in an IsExist error, but rather in an
+ // access denied error. To be sure, check for this case by checking
+ // whether the target directory exists.
+ if _, err := os.Stat(headerPath); err == nil {
+ break
+ }
+ fallthrough
+
+ default:
+ return nil, err
+ }
}
}
}