Proposal: overhaul System.Process

Simon Marlow marlowsd at gmail.com
Fri Jul 18 10:24:02 EDT 2008


Following Duncan's suggestions below, I have a further round of changes to 
the process library for comment.   The new Haddock docs are here:

  http://darcs.haskell.org/~simonmar/process/System-Process.html

Here is the patch message:

   * More System.Process overhaul

   New functions:

     callProcess :: FilePath -> [String] -> IO ()
     callCommand :: String -> IO ()

     spawnProcess :: FilePath -> [String] -> IO ProcessHandle
     spawnCommand :: String -> IO ProcessHandle

   Changes:

     - system and rawSystem have been removed from System.Process again.
       (they were only there temporarily after the last round of changes,
       now callCommand and callProcess replace them respectively).

   On Unix systems we now use SIGCHLD to detect process completion
   instead of calling waitpid().  This has several advantages:

     - much cheaper: no extra OS threads to do the waiting
     - doesn't require -threaded to get non-blocking waitForProcess
     - waitForProcess can be interrupted
     - no zombies left around (only relevant on Unix)

   However, it relies on the new signal API (see separate proposal).  And
   these advantages aren't available on Windows (yet).

Cheers,
	Simon


Duncan Coutts wrote:
> On Thu, 2008-05-15 at 10:45 +0100, Simon Marlow wrote:
>> The latest version of the Process overhaul is here:
>>
>>   http://darcs.haskell.org/~simonmar/process/System-Process.html
> 
> 
> We discussed some ideas on #ghc today and I'm posting them here so
> people can comment.
> 
> 
>  Deprecate:
>       * runCommand
>       * runProcess
>       * runInteractiveCommand
>       * runInteractiveCommand
> 
> The rationale is that these are all more limited than the new
> createProcess and yet none of them are really convenient. It's better to
> have fewer variations if they can all be expressed easily using
> createProcess. It makes the API much simpler.
> 
> Also we'd not add `system` or `rawSystem` to `System.Process` and
> instead add new equivalents with more consistent names.
> 
> That would leave just:
> 
>       * createProcess
>       * readProcess
>       * readProcessWithExitCode
> 
> Then add the following:
> 
>       * callProcess :: FilePath -> [String] -> IO ()
>       * callCommand :: String -> IO ()
> 
> These would be synchronous like the current system and rawSystem. The
> difference is they would throw IOErrors on failure rather than returning
> the ExitCode which is so easily ignored.
> 
> These are of course only convenience functions. If someone wants the
> exit code it should be easy to do it via createProcess and
> waitForProcess. We need to make sure that is indeed the case.
> 
> We'd also add async versions of the above:
> 
>       * spawnProcess :: FilePath -> [String] -> IO ProcessHandle
>       * spawnCommand :: String -> IO ProcessHandle
> 
> that do not wait for the process to finish and return the ProcessHandle.
> Again these should be easy instances of createProcess. The docs should
> probably say as much so it's clear how to make minor variations.
> 
> We also discussed how it should be safe to GC the ProcessHandle and not
> end up with zombie processes on unix systems. On Windows it's actually
> easy because you can close the process handle which means you don't get
> the exit status of the process. On unix we have to collect the exit
> status of every child process (actually you can ignore all of them, but
> you cannot ignore them selectively).
> 
> The point is that with a convenient spawnProcess it's tempting to ignore
> the ProcessHandle result and never bother calling waitForProcess on it.
> We do want to support that. At the moment doing that would leave zombie
> processes.
> 
> We discussed a mechanism to allow GC'ing ProcessHandles that does not
> leave zombies. It'd probably involve keeping a Map PID (MVar ExitCode)
> and embedding a MVar ExitCode in the ProcessHandle. Then when we get
> notified that a child process terminated we would store the exit status
> in the MVar. Then waitForProcess would just wait on that MVar ExitCode.
> 
> The one thing we have left that we cannot express with createProcess is
> the behaviour with respect to ^C handling. For some processes we want to
> delegate ^C handling to that child process (eg imagine calling ghci).
> For others we want to handle ^C 'normally'. For details see #2301:
> http://hackage.haskell.org/trac/ghc/ticket/2301
> 
> 
> Duncan
> 
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries



More information about the Libraries mailing list