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.
Этот коммит содержится в:
родитель
e6fbad13c6
коммит
d5c0083085
1 изменённых файлов: 18 добавлений и 1 удалений
|
@ -4,6 +4,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tinygo-org/tinygo/compileopts"
|
"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)
|
err = os.Rename(temporaryHeaderPath, headerPath)
|
||||||
if err != nil {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче