@@ -27,23 +27,24 @@ import (
2727var globalCliPath string
2828var globalClangdPath string
2929var enableLogging bool
30- var asyncProcessing bool
3130
3231// Setup initializes global variables.
33- func Setup (cliPath string , clangdPath string , _enableLogging bool , _asyncProcessing bool ) {
32+ func Setup (cliPath string , clangdPath string , _enableLogging bool ) {
3433 globalCliPath = cliPath
3534 globalClangdPath = clangdPath
3635 enableLogging = _enableLogging
37- asyncProcessing = _asyncProcessing
3836}
3937
4038// CLangdStarter starts clangd and returns its stdin/out/err
4139type CLangdStarter func () (stdin io.WriteCloser , stdout io.ReadCloser , stderr io.ReadCloser )
4240
4341// InoHandler is a JSON-RPC handler that delegates messages to clangd.
4442type InoHandler struct {
45- StdioConn * jsonrpc2.Conn
46- ClangdConn * jsonrpc2.Conn
43+ StdioConn * jsonrpc2.Conn
44+ ClangdConn * jsonrpc2.Conn
45+
46+ clangdStarted * sync.Cond
47+ dataMux sync.RWMutex
4748 lspInitializeParams * lsp.InitializeParams
4849 buildPath * paths.Path
4950 buildSketchRoot * paths.Path
@@ -61,8 +62,7 @@ type InoHandler struct {
6162 docs map [string ]* lsp.TextDocumentItem
6263 inoDocsWithDiagnostics map [string ]bool
6364
64- config lsp.BoardConfig
65- synchronizer Synchronizer
65+ config lsp.BoardConfig
6666}
6767
6868// NewInoHandler creates and configures an InoHandler.
@@ -74,15 +74,9 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
7474 SelectedBoard : board ,
7575 },
7676 }
77-
77+ handler . clangdStarted = sync . NewCond ( & handler . dataMux )
7878 stdStream := jsonrpc2 .NewBufferedStream (stdio , jsonrpc2.VSCodeObjectCodec {})
7979 var stdHandler jsonrpc2.Handler = jsonrpc2 .HandlerWithError (handler .HandleMessageFromIDE )
80- if asyncProcessing {
81- stdHandler = AsyncHandler {
82- handler : stdHandler ,
83- synchronizer : & handler .synchronizer ,
84- }
85- }
8680 handler .StdioConn = jsonrpc2 .NewConn (context .Background (), stdStream , stdHandler )
8781 if enableLogging {
8882 log .Println ("Initial board configuration:" , board )
@@ -118,11 +112,23 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
118112 "textDocument/didClose" : true ,
119113 }
120114 if needsWriteLock [req .Method ] {
121- handler .synchronizer . DataMux .Lock ()
122- defer handler .synchronizer . DataMux .Unlock ()
115+ handler .dataMux .Lock ()
116+ defer handler .dataMux .Unlock ()
123117 } else {
124- handler .synchronizer .DataMux .RLock ()
125- defer handler .synchronizer .DataMux .RUnlock ()
118+ handler .dataMux .RLock ()
119+ defer handler .dataMux .RUnlock ()
120+ }
121+
122+ // Wait for clangd start-up
123+ doNotNeedClangd := map [string ]bool {
124+ "initialize" : true ,
125+ "initialized" : true ,
126+ }
127+ if handler .ClangdConn == nil && ! doNotNeedClangd [req .Method ] {
128+ handler .clangdStarted .Wait ()
129+ if handler .ClangdConn == nil {
130+ return nil , errors .New ("could not run clangd, aborted" )
131+ }
126132 }
127133
128134 // Handle LSP methods: transform parameters and send to clangd
0 commit comments