@@ -97,10 +97,21 @@ func (handler *InoHandler) dataRUnlock(msg string) {
9797 handler .dataMux .RUnlock ()
9898}
9999
100- func (handler * InoHandler ) waitClangdStart (msg string ) {
101- log .Println (msg + yellow .Sprintf (" unlocked (waiting clangd)" ))
100+ func (handler * InoHandler ) waitClangdStart (prefix string ) error {
101+ if handler .ClangdConn != nil {
102+ return nil
103+ }
104+
105+ log .Printf (prefix + "(throttled: waiting for clangd)" )
106+ log .Println (prefix + yellow .Sprintf (" unlocked (waiting clangd)" ))
102107 handler .clangdStarted .Wait ()
103- log .Println (msg + yellow .Sprintf (" locked (waiting clangd)" ))
108+ log .Println (prefix + yellow .Sprintf (" locked (waiting clangd)" ))
109+
110+ if handler .ClangdConn == nil {
111+ log .Printf (prefix + "clangd startup failed: aborting call" )
112+ return errors .New ("could not start clangd, aborted" )
113+ }
114+ return nil
104115}
105116
106117// NewInoHandler creates and configures an InoHandler.
@@ -165,37 +176,35 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
165176 params = req .Params
166177 }
167178
179+ // Set up RWLocks and wait for clangd startup
168180 switch req .Method {
169- case // Write lock
170- "initialize" ,
181+ case // Write lock - NO clangd required
182+ "initialize" :
183+ handler .dataLock (prefix )
184+ defer handler .dataUnlock (prefix )
185+ case // Write lock - clangd required
171186 "textDocument/didOpen" ,
172187 "textDocument/didChange" ,
173188 "textDocument/didClose" :
174189 handler .dataLock (prefix )
175190 defer handler .dataUnlock (prefix )
176- case // Read lock
177- "textDocument/publishDiagnostics" ,
178- "workspace/applyEdit " :
191+ handler . waitClangdStart ( prefix )
192+ case // Read lock - NO clangd required
193+ "initialized " :
179194 handler .dataRLock (prefix )
180195 defer handler .dataRUnlock (prefix )
181- default : // Default to read lock
196+ default : // Read lock - clangd required
182197 handler .dataRLock (prefix )
183- defer handler .dataRUnlock (prefix )
184- }
185-
186- switch req .Method {
187- case // Do not need clangd
188- "initialize" ,
189- "initialized" :
190- default : // Default to clangd required
191- // Wait for clangd start-up
198+ // if clangd is not started...
192199 if handler .ClangdConn == nil {
193- log .Printf (prefix + "(throttled: waiting for clangd)" )
200+ // Release the read lock and acquire a write lock
201+ // (this is required to wait on condition variable).
202+ handler .dataRUnlock (prefix )
203+ handler .dataLock (prefix )
204+ defer handler .dataUnlock (prefix )
194205 handler .waitClangdStart (prefix )
195- if handler .ClangdConn == nil {
196- log .Printf (prefix + "clangd startup failed: aborting call" )
197- return nil , errors .New ("could not start clangd, aborted" )
198- }
206+ } else {
207+ defer handler .dataRUnlock (prefix )
199208 }
200209 }
201210
0 commit comments