From a739c973048b7e5b968f3b2c8bd0417a2fb01f99 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 28 Jan 2022 10:26:33 -0500 Subject: [PATCH] internal/lsp/fake: retry ioutil.ReadFile on plan9 if it fails due to exclusive use Fixes golang/go#50840. (Maybe.) Change-Id: I22d217f3706308b51d5b2ac84a781c50a6a41336 Reviewed-on: https://go-review.googlesource.com/c/tools/+/381734 Trust: Bryan Mills Run-TryBot: Bryan Mills gopls-CI: kokoro TryBot-Result: Gopher Robot Reviewed-by: Robert Findley --- internal/lsp/fake/workdir.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/lsp/fake/workdir.go b/internal/lsp/fake/workdir.go index c95fbe7165..8e28c020cd 100644 --- a/internal/lsp/fake/workdir.go +++ b/internal/lsp/fake/workdir.go @@ -12,6 +12,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" "sync" "time" @@ -152,11 +153,21 @@ func toURI(fp string) protocol.DocumentURI { // ReadFile reads a text file specified by a workdir-relative path. func (w *Workdir) ReadFile(path string) (string, error) { - b, err := ioutil.ReadFile(w.AbsPath(path)) - if err != nil { - return "", err + backoff := 1 * time.Millisecond + for { + b, err := ioutil.ReadFile(w.AbsPath(path)) + if err != nil { + if runtime.GOOS == "plan9" && strings.HasSuffix(err.Error(), " exclusive use file already open") { + // Plan 9 enforces exclusive access to locked files. + // Give the owner time to unlock it and retry. + time.Sleep(backoff) + backoff *= 2 + continue + } + return "", err + } + return string(b), nil } - return string(b), nil } func (w *Workdir) RegexpRange(path, re string) (Pos, Pos, error) {