From 97c4fbe5143a7dbf4d03b10562a0508d47ce2be4 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 7 Apr 2020 17:35:36 -0400 Subject: [PATCH] internal/lsp/protocol: make loggingStream log writes concurrency-safe Per the documentation for jsonrpc2.Stream Write must be safe for concurrent use, but this isn't the case for the loggingStream. Guard it with a mutex. Change-Id: I384892b90cef950d518089421d05cf8040c6b233 Reviewed-on: https://go-review.googlesource.com/c/tools/+/227487 Run-TryBot: Robert Findley TryBot-Result: Gobot Gobot Reviewed-by: Ian Cottrell --- internal/lsp/protocol/log.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/lsp/protocol/log.go b/internal/lsp/protocol/log.go index 1bb5c27fc0..30fa549539 100644 --- a/internal/lsp/protocol/log.go +++ b/internal/lsp/protocol/log.go @@ -14,23 +14,28 @@ import ( type loggingStream struct { stream jsonrpc2.Stream + logMu sync.Mutex log io.Writer } // LoggingStream returns a stream that does LSP protocol logging too func LoggingStream(str jsonrpc2.Stream, w io.Writer) jsonrpc2.Stream { - return &loggingStream{str, w} + return &loggingStream{stream: str, log: w} } func (s *loggingStream) Read(ctx context.Context) ([]byte, int64, error) { data, count, err := s.stream.Read(ctx) if err == nil { + s.logMu.Lock() + defer s.logMu.Unlock() logIn(s.log, data) } return data, count, err } func (s *loggingStream) Write(ctx context.Context, data []byte) (int64, error) { + s.logMu.Lock() + defer s.logMu.Unlock() logOut(s.log, data) count, err := s.stream.Write(ctx, data) return count, err