From 5bc242f3aec4f858894a4378a193c5dc847372e6 Mon Sep 17 00:00:00 2001 From: jneira Date: Tue, 9 Jul 2019 11:51:52 +0200 Subject: [PATCH] Shutdown the server before kill its thread --- src/Language/Haskell/LSP/Test.hs | 15 +-------------- src/Language/Haskell/LSP/Test/Session.hs | 11 ++++++++--- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/Language/Haskell/LSP/Test.hs b/src/Language/Haskell/LSP/Test.hs index e946cb7..5c41a7b 100644 --- a/src/Language/Haskell/LSP/Test.hs +++ b/src/Language/Haskell/LSP/Test.hs @@ -94,7 +94,6 @@ import qualified Data.Text.IO as T import Data.Aeson import Data.Default import qualified Data.HashMap.Strict as HashMap -import Data.IORef import qualified Data.Map as Map import Data.Maybe import Language.Haskell.LSP.Types @@ -139,7 +138,6 @@ runSessionWithConfig :: SessionConfig -- ^ Configuration options for the session -> IO a runSessionWithConfig config serverExe caps rootDir session = do -- We use this IORef to make exception non-fatal when the server is supposed to shutdown. - exitOk <- newIORef False pid <- getCurrentProcessID absRootDir <- canonicalizePath rootDir @@ -151,8 +149,7 @@ runSessionWithConfig config serverExe caps rootDir session = do (Just TraceOff) Nothing withServer serverExe (logStdErr config) $ \serverIn serverOut _ -> - runSessionWithHandles serverIn serverOut (\h c -> catchWhenTrue exitOk $ listenServer h c) config caps rootDir $ do - + runSessionWithHandles serverIn serverOut (\h c -> listenServer h c) config caps rootDir $ do -- Wrap the session around initialize and shutdown calls initRspMsg <- request Initialize initializeParams :: Session InitializeResponse @@ -169,18 +166,8 @@ runSessionWithConfig config serverExe caps rootDir session = do -- Run the actual test result <- session - - liftIO $ atomicWriteIORef exitOk True - sendNotification Exit ExitParams - return result where - catchWhenTrue :: IORef Bool -> IO () -> IO () - catchWhenTrue exitOk a = - a `catch` (\e -> do - x <- readIORef exitOk - unless x $ throw (e :: SomeException)) - -- | Listens to the server output, makes sure it matches the record and -- signals any semaphores -- Note that on Windows, we cannot kill a thread stuck in getNextMessage. diff --git a/src/Language/Haskell/LSP/Test/Session.hs b/src/Language/Haskell/LSP/Test/Session.hs index 46155f0..415402a 100644 --- a/src/Language/Haskell/LSP/Test/Session.hs +++ b/src/Language/Haskell/LSP/Test/Session.hs @@ -212,9 +212,11 @@ runSessionWithHandles serverIn serverOut serverHandler config caps rootDir sessi initState = SessionState (IdInt 0) mempty mempty 0 False Nothing launchServerHandler = forkIO $ catch (serverHandler serverOut context) (throwTo mainThreadId :: SessionException -> IO()) - (result, _) <- bracket launchServerHandler killThread $ - const $ runSession context initState session - + (result, _) <- bracket + launchServerHandler + (\tid -> do runSession context initState sendExitMessage + killThread tid) + (const $ runSession context initState session) return result updateStateC :: ConduitM FromServerMessage FromServerMessage (StateT SessionState (ReaderT SessionContext IO)) () @@ -301,6 +303,9 @@ sendMessage msg = do logMsg LogClient msg liftIO $ B.hPut h (addHeader $ encode msg) +sendExitMessage :: (MonadIO m, HasReader SessionContext m) => m () +sendExitMessage = sendMessage (NotificationMessage "2.0" Exit ExitParams) + -- | Execute a block f that will throw a 'Timeout' exception -- after duration seconds. This will override the global timeout -- for waiting for messages to arrive defined in 'SessionConfig'. -- 2.30.2