[Haskell-cafe] Re: getChar + System.Cmd.system + threads causes hangups

2006-02-22 Thread Simon Marlow

Donn Cave wrote:

On Tue, 21 Feb 2006, Simon Marlow wrote:


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).



I was puzzled by this;  from a quick review of the source, it seems
that this is because system calls runProcessPosix, which has optional
arguments for (stdin, stdout, stderr) for the child process, and when
value is Nothing the parent's stdin etc. are used instead.

That last part doesn't seem right to me, so if it's awkward to implement,
I hope you will consider the possibility that no one needs it.  The
default value for fd 0 should be fd 0.  A process that intends to change
the default input stream on this level where the same stream should be
inherited by children, can open or dup another file onto fd 0.  Conversely,
if a program contrives to change stdin to something besides fd 0, I would
have assumed the intent was to avoid any affect on child processes.


That's certainly a reasonable point of view.  Currently the semantics 
are such that you can say


  h - openFile out WriteMode
  hDuplicateTo h stdout
  system echo \hello\

and the output from the echo command will go to the file out.

I'm perfectly willing to accept that supporting this behaviour is of 
limited usefulness, and even if you need it then you can call system the 
long way using runProcess.


Anyone else have any opinions on this?

Cheers,
Simon

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: getChar + System.Cmd.system + threads causes hangups

2006-02-21 Thread Simon Marlow

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 10  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 10  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


Re: [Haskell-cafe] Re: getChar + System.Cmd.system + threads causes hangups

2006-02-21 Thread Donn Cave
On Tue, 21 Feb 2006, Simon Marlow wrote:
...
 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).

I was puzzled by this;  from a quick review of the source, it seems
that this is because system calls runProcessPosix, which has optional
arguments for (stdin, stdout, stderr) for the child process, and when
value is Nothing the parent's stdin etc. are used instead.

That last part doesn't seem right to me, so if it's awkward to implement,
I hope you will consider the possibility that no one needs it.  The
default value for fd 0 should be fd 0.  A process that intends to change
the default input stream on this level where the same stream should be
inherited by children, can open or dup another file onto fd 0.  Conversely,
if a program contrives to change stdin to something besides fd 0, I would
have assumed the intent was to avoid any affect on child processes.

Donn Cave, [EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe