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"
 | 
			
		||||
	"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
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче