From 09f9cfa88292dd2b01eb8fc08387898ff3561f27 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Mon, 29 Jul 2019 20:48:11 -0700 Subject: [PATCH] internal/lsp: set initialized state Set the server state to initialized so that dynamic configuration requests will be sent to the client. Rename the mutex that guards state. The state field was previously named initialized, so it only makes sense to similarly rename the mutex that guards the state field. Always unlock stateMu before calling other functions so that callees that need to check state can acquire the lock. Change-Id: Ia5592ca1dedfc6f004ae6b61548890624ae98d59 Reviewed-on: https://go-review.googlesource.com/c/tools/+/188097 Run-TryBot: Rebecca Stambler TryBot-Result: Gobot Gobot Reviewed-by: Ian Cottrell --- internal/lsp/general.go | 19 ++++++++++++++----- internal/lsp/server.go | 4 ++-- internal/lsp/workspace.go | 5 ++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/internal/lsp/general.go b/internal/lsp/general.go index a6549beb..cd9ac7aa 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -21,12 +21,15 @@ import ( ) func (s *Server) initialize(ctx context.Context, params *protocol.InitializeParams) (*protocol.InitializeResult, error) { - s.initializedMu.Lock() - defer s.initializedMu.Unlock() - if s.state >= serverInitializing { + s.stateMu.Lock() + state := s.state + s.stateMu.Unlock() + if state >= serverInitializing { return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server already initialized") } + s.stateMu.Lock() s.state = serverInitializing + s.stateMu.Unlock() // TODO: Remove the option once we are certain there are no issues here. s.textDocumentSyncKind = protocol.Incremental @@ -127,6 +130,10 @@ func (s *Server) setClientCapabilities(caps protocol.ClientCapabilities) { } func (s *Server) initialized(ctx context.Context, params *protocol.InitializedParams) error { + s.stateMu.Lock() + s.state = serverInitialized + s.stateMu.Unlock() + if s.configurationSupported { if s.dynamicConfigurationSupported { s.client.RegisterCapability(ctx, &protocol.RegistrationParams{ @@ -249,8 +256,8 @@ func (s *Server) processConfig(ctx context.Context, view source.View, config int } func (s *Server) shutdown(ctx context.Context) error { - s.initializedMu.Lock() - defer s.initializedMu.Unlock() + s.stateMu.Lock() + defer s.stateMu.Unlock() if s.state < serverInitialized { return jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server not initialized") } @@ -261,6 +268,8 @@ func (s *Server) shutdown(ctx context.Context) error { } func (s *Server) exit(ctx context.Context) error { + s.stateMu.Lock() + defer s.stateMu.Unlock() if s.state != serverShutDown { os.Exit(1) } diff --git a/internal/lsp/server.go b/internal/lsp/server.go index ae9333d5..26d2c216 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -73,8 +73,8 @@ type Server struct { Conn *jsonrpc2.Conn client protocol.Client - initializedMu sync.Mutex - state serverState + stateMu sync.Mutex + state serverState // Configurations. // TODO(rstambler): Separate these into their own struct? diff --git a/internal/lsp/workspace.go b/internal/lsp/workspace.go index 9ad21d17..8ad41af1 100644 --- a/internal/lsp/workspace.go +++ b/internal/lsp/workspace.go @@ -32,7 +32,10 @@ func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFold func (s *Server) addView(ctx context.Context, name string, uri span.URI) error { view := s.session.NewView(ctx, name, uri) - if s.state >= serverInitialized { + s.stateMu.Lock() + state := s.state + s.stateMu.Unlock() + if state >= serverInitialized { s.fetchConfig(ctx, view) } return nil