@@ -142,6 +142,11 @@ setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
142
142
reactorLifetime <- newEmptyMVar
143
143
let stopReactorLoop = void $ tryPutMVar reactorLifetime ()
144
144
145
+ -- An MVar to control the lifetime of the reactor loop.
146
+ -- The loop will be stopped and resources freed when it's full
147
+ waitForReactor <- newEmptyMVar
148
+ let finishEndReactor = void $ tryPutMVar waitForReactor ()
149
+
145
150
-- Forcefully exit
146
151
let exit = void $ tryPutMVar clientMsgVar ()
147
152
@@ -166,17 +171,18 @@ setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
166
171
cancelled <- readTVar cancelledRequests
167
172
unless (reqId `Set.member` cancelled) retry
168
173
174
+
175
+ let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan finishEndReactor
176
+
169
177
let asyncHandlers = mconcat
170
178
[ userHandlers
171
179
, cancelHandler cancelRequest
172
- , exitHandler $ stopReactorLoop >> exit
180
+ , exitHandler $ stopReactorLoop >> takeMVar waitForReactor >> exit
173
181
, shutdownHandler stopReactorLoop
174
182
]
175
183
-- Cancel requests are special since they need to be handled
176
184
-- out of order to be useful. Existing handlers are run afterwards.
177
185
178
- let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan
179
-
180
186
let interpretHandler (env, st) = LSP. Iso (LSP. runLspT env . flip (runReaderT . unServerM) (clientMsgChan,st)) liftIO
181
187
182
188
pure (doInitialize, asyncHandlers, interpretHandler)
@@ -191,8 +197,10 @@ handleInit
191
197
-> (SomeLspId -> IO () )
192
198
-> (SomeLspId -> IO () )
193
199
-> Chan ReactorMessage
194
- -> LSP. LanguageContextEnv config -> TRequestMessage Method_Initialize -> IO (Either err (LSP. LanguageContextEnv config , IdeState ))
195
- handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan env (TRequestMessage _ _ m params) = otTracedHandler " Initialize" (show m) $ \ sp -> do
200
+ -> IO ()
201
+ -> LSP. LanguageContextEnv config -> TRequestMessage Method_Initialize
202
+ -> IO (Either err (LSP. LanguageContextEnv config , IdeState ))
203
+ handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan finishEndReactor env (TRequestMessage _ _ m params) = otTracedHandler " Initialize" (show m) $ \ sp -> do
196
204
traceWithSpan sp params
197
205
let root = LSP. resRootPath env
198
206
dir <- maybe getCurrentDirectory return root
@@ -245,6 +253,7 @@ handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId wa
245
253
ReactorNotification act -> handle exceptionInHandler act
246
254
ReactorRequest _id act k -> void $ async $ checkCancelled _id act k
247
255
logWith recorder Info LogReactorThreadStopped
256
+ finishEndReactor
248
257
pure $ Right (env,ide)
249
258
250
259
0 commit comments