diff options
author | Dan Willemsen <dwillemsen@google.com> | 2017-10-18 13:18:41 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2017-10-18 15:09:08 -0700 |
commit | ca8feb385c9bf1ad4bf884a0b8a4defd9e707a0b (patch) | |
tree | 7259d16d3951894ed70ea4e9bd9c980bc89205ae /ui | |
parent | 31b59cf6041fa8c6d7c8a74ebec14c6618bc49ae (diff) | |
download | build_soong-ca8feb385c9bf1ad4bf884a0b8a4defd9e707a0b.tar.gz build_soong-ca8feb385c9bf1ad4bf884a0b8a4defd9e707a0b.tar.bz2 build_soong-ca8feb385c9bf1ad4bf884a0b8a4defd9e707a0b.zip |
Synchronize file rotation
Create a lock file during log rotation so that multiple processes won't
step on each other.
Test: Run `while true; do get_build_var TARGET_PRODUCT; done` in parallel
Test: m blueprint_tools
Change-Id: I7144cd42aca47c694487ddae44713f82665ed81e
Diffstat (limited to 'ui')
-rw-r--r-- | ui/logger/logger.go | 16 | ||||
-rw-r--r-- | ui/logger/logger_test.go | 2 |
2 files changed, 14 insertions, 4 deletions
diff --git a/ui/logger/logger.go b/ui/logger/logger.go index 7d9687be..15c413dd 100644 --- a/ui/logger/logger.go +++ b/ui/logger/logger.go @@ -38,6 +38,7 @@ import ( "path/filepath" "strconv" "sync" + "syscall" ) type Logger interface { @@ -93,10 +94,19 @@ func fileRotation(from, baseName, ext string, cur, max int) error { // existing files to <filename>.#.<ext>, keeping up to maxCount files. // <filename>.1.<ext> is the most recent backup, <filename>.2.<ext> is the // second most recent backup, etc. -// -// TODO: This function is not guaranteed to be atomic, if there are multiple -// users attempting to do the same operation, the result is undefined. func CreateFileWithRotation(filename string, maxCount int) (*os.File, error) { + lockFileName := filepath.Join(filepath.Dir(filename), ".lock_"+filepath.Base(filename)) + lockFile, err := os.OpenFile(lockFileName, os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + return nil, err + } + defer lockFile.Close() + + err = syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX) + if err != nil { + return nil, err + } + if _, err := os.Lstat(filename); err == nil { ext := filepath.Ext(filename) basename := filename[:len(filename)-len(ext)] diff --git a/ui/logger/logger_test.go b/ui/logger/logger_test.go index 0f88ab37..dc6f2e91 100644 --- a/ui/logger/logger_test.go +++ b/ui/logger/logger_test.go @@ -67,7 +67,7 @@ func TestCreateFileWithRotation(t *testing.T) { t.Fatalf("Failed to read dir: %v", err) } sort.Strings(names) - expected := []string{"build.1.log", "build.2.log", "build.3.log", "build.log"} + expected := []string{".lock_build.log", "build.1.log", "build.2.log", "build.3.log", "build.log"} if !reflect.DeepEqual(names, expected) { t.Errorf("File list does not match.") t.Errorf(" got: %v", names) |