Add a finally and timeout to ensure the call to killThread
[lsp-test.git] / src / Language / Haskell / LSP / Test / Session.hs
index 46155f0607cfa1b752b541b755a761b1551b4b30..21a5fe7002af4061552c390bbc24442bec4786d2 100644 (file)
@@ -65,6 +65,7 @@ import Language.Haskell.LSP.Test.Exceptions
 import System.Console.ANSI
 import System.Directory
 import System.IO
+import System.Timeout
 
 -- | A session representing one instance of launching and connecting to a server.
 --
@@ -190,9 +191,11 @@ runSessionWithHandles :: Handle -- ^ Server in
                       -> SessionConfig
                       -> ClientCapabilities
                       -> FilePath -- ^ Root directory
+                      -> Session () -- ^ To exit Server
                       -> Session a
                       -> IO a
-runSessionWithHandles serverIn serverOut serverHandler config caps rootDir session = do
+runSessionWithHandles serverIn serverOut serverHandler config caps rootDir exitServer session = do
+  
   absRootDir <- canonicalizePath rootDir
 
   hSetBuffering serverIn  NoBuffering
@@ -210,11 +213,14 @@ runSessionWithHandles serverIn serverOut serverHandler config caps rootDir sessi
 
   let context = SessionContext serverIn absRootDir messageChan reqMap initRsp config caps
       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
+      runSession' = runSession context initState
+      
+      errorHandler = throwTo mainThreadId :: SessionException -> IO()
+      serverLauncher = forkIO $ catch (serverHandler serverOut context) errorHandler
+      serverFinalizer tid = finally (timeout 60000000 (runSession' exitServer))
+                                    (killThread tid)
       
+  (result, _) <- bracket serverLauncher serverFinalizer (const $ runSession' session)
   return result
 
 updateStateC :: ConduitM FromServerMessage FromServerMessage (StateT SessionState (ReaderT SessionContext IO)) ()