@@ -97,10 +97,21 @@ func (handler *InoHandler) dataRUnlock(msg string) {
97
97
handler .dataMux .RUnlock ()
98
98
}
99
99
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)" ))
102
107
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
104
115
}
105
116
106
117
// NewInoHandler creates and configures an InoHandler.
@@ -165,37 +176,35 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
165
176
params = req .Params
166
177
}
167
178
179
+ // Set up RWLocks and wait for clangd startup
168
180
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
171
186
"textDocument/didOpen" ,
172
187
"textDocument/didChange" ,
173
188
"textDocument/didClose" :
174
189
handler .dataLock (prefix )
175
190
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 " :
179
194
handler .dataRLock (prefix )
180
195
defer handler .dataRUnlock (prefix )
181
- default : // Default to read lock
196
+ default : // Read lock - clangd required
182
197
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...
192
199
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 )
194
205
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 )
199
208
}
200
209
}
201
210
0 commit comments