Hello, it looks like a scope may not terminate properly when reading the output of an external process using hGetLine.
When running the following example I get:
$ cabal run ki-blocked-repro.hs
Cat is running...
Cat is running...
Exiting main scope...
C-c C-ccabal-script-ki-blocked-repro.hs: thread blocked indefinitely in an STM transaction
The program hangs until it is interrupted with Ctrl-C.
When trying to minify the reproducer, I noticed that removing the nested scope, by replacing Ki.scoped catAction with catAction scope, the issue disappear: the program exit cleanly. Thus it seems like a bug in ki, but I can't tell the root cause, and perhaps it's related to the process library and how the exceptions are masked?
{- cabal:
build-depends: base, bytestring, ki, typed-process
ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T
-}
module Main where
import Control.Concurrent (threadDelay)
import Control.Monad (forever)
import qualified Data.ByteString as BS
import qualified Ki as Ki
import qualified System.Process.Typed as ProcessTyped
catAction :: Ki.Scope -> IO ()
catAction scope =
ProcessTyped.withProcessWait_ cmd $ \p -> do
Ki.fork_ scope $ forever $ BS.hGetLine (ProcessTyped.getStdout p)
forever $ do
putStrLn $ "Cat is running..."
threadDelay 300000
where
cmd =
ProcessTyped.setStdout ProcessTyped.createPipe $
ProcessTyped.proc "cat" []
main :: IO ()
main = do
Ki.scoped $ \scope -> do
_ <- scope `Ki.fork` Ki.scoped catAction
threadDelay 500000
putStrLn "Exiting main scope..."
putStrLn "This is the end."
Hello, it looks like a scope may not terminate properly when reading the output of an external process using
hGetLine.When running the following example I get:
The program hangs until it is interrupted with Ctrl-C.
When trying to minify the reproducer, I noticed that removing the nested scope, by replacing
Ki.scoped catActionwithcatAction scope, the issue disappear: the program exit cleanly. Thus it seems like a bug inki, but I can't tell the root cause, and perhaps it's related to the process library and how the exceptions are masked?