@@ -142,6 +142,11 @@ setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
142142 reactorLifetime <- newEmptyMVar
143143 let stopReactorLoop = void $ tryPutMVar reactorLifetime ()
144144
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+
145150 -- Forcefully exit
146151 let exit = void $ tryPutMVar clientMsgVar ()
147152
@@ -166,17 +171,18 @@ setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
166171 cancelled <- readTVar cancelledRequests
167172 unless (reqId `Set.member` cancelled) retry
168173
174+
175+ let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan finishEndReactor
176+
169177 let asyncHandlers = mconcat
170178 [ userHandlers
171179 , cancelHandler cancelRequest
172- , exitHandler $ stopReactorLoop >> exit
180+ , exitHandler $ stopReactorLoop >> takeMVar waitForReactor >> exit
173181 , shutdownHandler stopReactorLoop
174182 ]
175183 -- Cancel requests are special since they need to be handled
176184 -- out of order to be useful. Existing handlers are run afterwards.
177185
178- let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan
179-
180186 let interpretHandler (env, st) = LSP. Iso (LSP. runLspT env . flip (runReaderT . unServerM) (clientMsgChan,st)) liftIO
181187
182188 pure (doInitialize, asyncHandlers, interpretHandler)
@@ -191,8 +197,10 @@ handleInit
191197 -> (SomeLspId -> IO () )
192198 -> (SomeLspId -> IO () )
193199 -> 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
196204 traceWithSpan sp params
197205 let root = LSP. resRootPath env
198206 dir <- maybe getCurrentDirectory return root
@@ -245,6 +253,7 @@ handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId wa
245253 ReactorNotification act -> handle exceptionInHandler act
246254 ReactorRequest _id act k -> void $ async $ checkCancelled _id act k
247255 logWith recorder Info LogReactorThreadStopped
256+ finishEndReactor
248257 pure $ Right (env,ide)
249258
250259
0 commit comments