Einar Karttunen wrote:
Hello

Using system or any variant of it from System.Process
seems broken in multithreaded environments. This
example will fail with and without -threaded.

When run the program will print "hello: start" and
then freeze. After pressing enter (the first getChar)
System.Cmd.system will complete, but without that
it will freeze for all eternity.

What is the best way to fix this? I could use System.Posix,
but that would lose windows portablity which is needed.

import Control.Concurrent
import System.Cmd

main = do forkIO (threadDelay 100000 >> hello)
          getChar
          getChar

hello = do putStrLn "hello: start"
           system "echo hello world!"
           putStrLn "hello: done"

The reason for the deadlock is because getChar is holding a lock on stdin, and System.Cmd.system needs to access the stdin Handle in order to know which file descriptor to dup as stdin in the child process (the stdin Handle isn't always FD 0, because of hDuplicateTo).

Maybe getChar shouldn't hold the lock while it is waiting. I was vaguely aware of this when I wrote System.IO, but couldn't see an easy way to implement it, so currently all operations that block in I/O hold the Handle lock while they block. Mostly this isn't a problem, but it does mean that things like hClose will block if there's another thread blocked in hGetChar on the same Handle (maybe you want it to cause the hGetChar to immediately fail instead).

One way to work around it in this case is to hDuplicate the standard Handles, and call runProcess passing your duplicate Handles. I've just checked; this works fine.

import GHC.Handle (hDuplicate)

main = do
 i <- hDuplicate stdin
 o <- hDuplicate stdout
 e <- hDuplicate stderr
 forkIO (threadDelay 100000 >> hello i o e)
 getChar
 getChar

hello i o e = do
  putStrLn "hello: start"
p <- runProcess "echo" ["hello world!"] Nothing Nothing (Just i) (Just o) (Just e)
  waitForProcess p
  putStrLn "hello: done"

Cheers,
        Simon
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to