@@ -8,8 +8,9 @@ module Test.DocTest.Internal.Runner where
88import Prelude hiding (putStr , putStrLn , error )
99
1010import Control.Concurrent (Chan , writeChan , readChan , newChan , forkIO , ThreadId , myThreadId , MVar , newMVar )
11- import Control.Exception (SomeException , catch )
11+ import Control.Exception (SomeException )
1212import Control.Monad hiding (forM_ )
13+ import Control.Monad.Catch (catch )
1314import Data.Foldable (forM_ )
1415import Data.Function (on )
1516import Data.List (sortBy )
@@ -30,15 +31,18 @@ import Test.DocTest.Internal.Options
3031 , cfgRandomizeOrder , cfgImplicitModuleImport , parseLocatedModuleOptions )
3132import Test.DocTest.Internal.Location
3233import qualified Test.DocTest.Internal.Property as Property
33- import Test.DocTest.Internal.Runner.Example
34- import Test.DocTest.Internal.Logging (LogLevel (.. ), formatLog , shouldLog , getThreadName )
3534import Test.DocTest.Internal.Extract (isEmptyModule )
35+ import Test.DocTest.Internal.GhcUtil (withGhc )
36+ import Test.DocTest.Internal.Logging (LogLevel (.. ), formatLog , shouldLog , getThreadName )
37+ import Test.DocTest.Internal.Runner.Example
3638
3739import System.IO.CodePage (withCP65001 )
3840import Control.Monad.Extra (whenM )
41+ import GHC (Ghc )
3942
4043#ifdef mingw32_HOST_OS
41- import Control.Concurrent.MVar (withMVar )
44+ import Control.Concurrent.MVar (putMVar , takeMVar )
45+ import Control.Monad.Catch (finally )
4246#endif
4347
4448#if __GLASGOW_HASKELL__ < 804
@@ -101,7 +105,8 @@ runModules modConfig nThreads implicitPrelude parseArgs evalArgs modules = do
101105 (input, output) <-
102106 makeThreadPool
103107 (fromMaybe nCores nThreads)
104- (runModule modConfig implicitPrelude ghcLock parseArgs evalArgs)
108+ parseArgs
109+ (runModule modConfig implicitPrelude ghcLock evalArgs)
105110
106111 -- Send instructions to threads
107112 liftIO (mapM_ (writeChan input) modules)
@@ -207,31 +212,30 @@ runModule
207212 -> MVar ()
208213 -- ^ GHC lock
209214 -> [String ]
210- -- ^ Parse GHC arguments
211- -> [String ]
212215 -- ^ Eval GHCi arguments
213216 -> Chan (ThreadId , ReportUpdate )
214217 -> ModuleName
215- -> IO ()
216- runModule modConfig0 implicitPrelude ghcLock parseArgs evalArgs output modName = do
217- threadId <- myThreadId
218+ -> Ghc ()
219+ runModule modConfig0 implicitPrelude ghcLock evalArgs output modName = do
220+ threadId <- liftIO myThreadId
218221 let update r = writeChan output (threadId, r)
219222
220- mod_@ (Module module_ setup examples0 modArgs) <-
223+ mod_@ (Module module_ setup examples0 modArgs) <- do
221224#ifdef mingw32_HOST_OS
222225 -- XXX: Cannot use multiple GHC APIs at the same time on Windows
223- withMVar ghcLock $ \ () ->
226+ liftIO $ takeMVar ghcLock
227+ getDocTests modName `finally` liftIO (putMVar ghcLock () )
224228#else
225- ghcLock `seq`
229+ ghcLock `seq` getDocTests modName
226230#endif
227- getDocTests parseArgs modName
228- update (UpdateModuleParsed modName (count (Module module_ setup examples0 modArgs)))
231+
232+ liftIO $ update (UpdateModuleParsed modName (count (Module module_ setup examples0 modArgs)))
229233 let modConfig2 = parseLocatedModuleOptions modName modConfig0 modArgs
230234
231235 unless (isEmptyModule mod_) $
232236 case modConfig2 of
233237 Left (loc, flag) ->
234- update (UpdateOptionError loc flag)
238+ liftIO $ update (UpdateOptionError loc flag)
235239
236240 Right modConfig3 -> do
237241 let
@@ -267,7 +271,7 @@ runModule modConfig0 implicitPrelude ghcLock parseArgs evalArgs output modName =
267271
268272
269273 let logger = update . UpdateLog Debug
270- Interpreter. withInterpreter logger evalArgs $ \ repl -> withCP65001 $ do
274+ liftIO $ Interpreter. withInterpreter logger evalArgs $ \ repl -> withCP65001 $ do
271275 -- Try to import this module, if it fails, something is off
272276 importResult <-
273277 case importModule of
@@ -292,7 +296,7 @@ runModule modConfig0 implicitPrelude ghcLock parseArgs evalArgs output modName =
292296 update (UpdateImportError module_ importResult)
293297
294298 -- Signal main thread a module has been tested
295- update UpdateModuleDone
299+ liftIO $ update UpdateModuleDone
296300
297301data ReportUpdate
298302 = UpdateSuccess FromSetup
@@ -316,18 +320,19 @@ data ReportUpdate
316320
317321makeThreadPool ::
318322 Int ->
319- (Chan (ThreadId , ReportUpdate ) -> ModuleName -> IO () ) ->
323+ [String ] ->
324+ (Chan (ThreadId , ReportUpdate ) -> ModuleName -> Ghc () ) ->
320325 IO (Chan ModuleName , Chan (ThreadId , ReportUpdate ))
321- makeThreadPool nThreads mutator = do
326+ makeThreadPool nThreads parseArgs mutator = do
322327 input <- newChan
323328 output <- newChan
324329 forM_ [1 .. nThreads] $ \ _ ->
325- forkIO $ forever $ do
326- modName <- readChan input
327- threadId <- myThreadId
330+ forkIO $ withGhc parseArgs $ forever $ do
331+ modName <- liftIO $ readChan input
332+ threadId <- liftIO myThreadId
328333 catch
329334 (mutator output modName)
330- (\ e -> writeChan output (threadId, UpdateInternalError modName e))
335+ (\ e -> liftIO $ writeChan output (threadId, UpdateInternalError modName e))
331336 return (input, output)
332337
333338reportModuleParsed :: (? verbosity :: LogLevel , ? threadId :: ThreadId ) => ModuleName -> Int -> Report ()
0 commit comments