Skip to content

Commit

Permalink
internal/lsp/cache: fix mod file change check
Browse files Browse the repository at this point in the history
The modfiles function only works with Go 1.14. When it is enabled,
it reenters the view, causing a deadlock. Stop using it, and move the
process env under a separate lock so to break the deadlock.

Change-Id: I34c528c2be1f32c06b423ead44e90155f60c2214
Reviewed-on: https://go-review.googlesource.com/c/tools/+/215679
Run-TryBot: Heschi Kreinick <[email protected]>
Reviewed-by: Rebecca Stambler <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
heschi committed Jan 21, 2020
1 parent 13c7480 commit 9375b12
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions internal/lsp/cache/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ type view struct {
// mod is the module information for this view.
mod *moduleInformation

// importsMu guards imports-related state, particularly the ProcessEnv.
importsMu sync.Mutex
// process is the process env for this view.
// Note: this contains cached module and filesystem state.
//
Expand Down Expand Up @@ -274,8 +276,9 @@ func (v *view) Config(ctx context.Context) *packages.Config {
}

func (v *view) RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options) error) error {
v.mu.Lock()
defer v.mu.Unlock()
v.importsMu.Lock()
defer v.importsMu.Unlock()

if v.processEnv == nil {
var err error
if v.processEnv, err = v.buildProcessEnv(ctx); err != nil {
Expand All @@ -284,11 +287,12 @@ func (v *view) RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options)
}

// In module mode, check if the mod file has changed.
if mod, _, err := v.Snapshot().ModFiles(ctx); err == nil && mod != nil {
if mod.Identity() != v.cachedModFileVersion {
if v.gomod != "" && v.gomod != os.DevNull {
mod, err := v.Snapshot().GetFile(span.FileURI(v.gomod))
if err == nil && mod.Identity() != v.cachedModFileVersion {
v.processEnv.GetResolver().(*imports.ModuleResolver).ClearForNewMod()
v.cachedModFileVersion = mod.Identity()
}
v.cachedModFileVersion = mod.Identity()
}

// Run the user function.
Expand Down Expand Up @@ -323,20 +327,20 @@ func (v *view) RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options)
func (v *view) refreshProcessEnv() {
start := time.Now()

v.mu.Lock()
v.importsMu.Lock()
env := v.processEnv
env.GetResolver().ClearForNewScan()
v.mu.Unlock()
v.importsMu.Unlock()

// We don't have a context handy to use for logging, so use the stdlib for now.
stdlog.Printf("background imports cache refresh starting")
err := imports.PrimeCache(context.Background(), env)
stdlog.Printf("background refresh finished after %v with err: %v", time.Since(start), err)

v.mu.Lock()
v.importsMu.Lock()
v.cacheRefreshDuration = time.Since(start)
v.cacheRefreshTimer = nil
v.mu.Unlock()
v.importsMu.Unlock()
}

func (v *view) buildProcessEnv(ctx context.Context) (*imports.ProcessEnv, error) {
Expand Down

0 comments on commit 9375b12

Please sign in to comment.