attempt to work around restrictions with fork() & pthreads
authorSimon Marlow <simonmar@microsoft.com>
Thu, 23 Mar 2006 13:40:34 +0000 (13:40 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Thu, 23 Mar 2006 13:40:34 +0000 (13:40 +0000)
In the child process, call exec() directly instead of using
System.Cmd.system, which involves another fork()/exec() and a
non-blocking wait.  The problem is that in a forked child of a
threaded process, it isn't safe to do much except exec() according to
POSIX.  In fact calling pthread_create() in the child causes the
pthread library to fail with an error on FreeBSD.

testsuite/timeout/timeout.hs

index d0c66b1..81f3ab4 100644 (file)
@@ -12,7 +12,7 @@ import System.Process
 import Control.Monad (when)\r
 #if !defined(mingw32_HOST_OS)\r
 import System.Process.Internals (mkProcessHandle)\r
-import System.Posix.Process (forkProcess, createSession)\r
+import System.Posix.Process (forkProcess, createSession, executeFile)\r
 import System.Posix.Signals (installHandler, Handler(Catch),\r
                              signalProcessGroup, sigINT, sigTERM, sigKILL )\r
 #endif\r
@@ -30,10 +30,7 @@ main = do
         forkIO (do threadDelay (read secs * 1000000)\r
                    putMVar m Nothing\r
                )\r
-        forkIO (do try (do pid <- forkProcess $ do\r
-                               createSession\r
-                               r <- system cmd\r
-                               exitWith r\r
+        forkIO (do try (do pid <- systemSession cmd\r
                           ph <- mkProcessHandle pid\r
                            putMVar mp (pid,ph)\r
                            r <- waitForProcess ph\r
@@ -51,6 +48,16 @@ main = do
     _other -> do hPutStrLn stderr "timeout: bad arguments"\r
                  exitWith (ExitFailure 1)\r
 \r
+systemSession cmd =  \r
+ forkProcess $ do\r
+   createSession\r
+   executeFile "/bin/sh" False ["-c", cmd] Nothing\r
+   -- need to use exec() directly here, rather than something like\r
+   -- System.Process.system, because we are in a forked child and some\r
+   -- pthread libraries get all upset if you start doing certain\r
+   -- things in a forked child of a pthread process, such as forking\r
+   -- more threads.\r
+\r
 killProcess pid ph = do\r
   try (signalProcessGroup sigTERM pid)\r
   checkReallyDead 10\r