-- Copyright: (c) 2013 GREE, Inc. -- License: MIT-style {-# LANGUAGE ScopedTypeVariables #-} module System.Prefork.Worker ( forkWorkerProcess , forkWorkerProcessWithArgs , preforkEnvKey ) where import Control.Monad import Control.Exception import System.Process import System.Process.Internals (withProcessHandle, ProcessHandle__(OpenHandle)) import Filesystem.Path.CurrentOS(encodeString) import System.Posix hiding (version) import Foreign.C.Types import System.IO (hPutStrLn) import System.Argv0 import Data.Maybe import System.Environment (lookupEnv) import System.IO import Control.Concurrent import System.Prefork.Class preforkEnvKey :: String preforkEnvKey = "PREFORK" {- | create a new worker with arguments -} forkWorkerProcessWithArgs :: (WorkerContext a) => a -- ^ a worker context -> [String] -- ^ command line arguments -> IO ProcessID -- ^ a process id of a created worker forkWorkerProcessWithArgs opt args = do exe <- liftM encodeString getArgv0 (Just hIn, Just hOut, _, ph) <- createProcess $ (proc exe options) { std_in = CreatePipe, std_out = CreatePipe } forkIO $ hPutStr stdout =<< hGetContents hOut hPutStrLn hIn $ encodeToString opt extractProcessID ph where options :: [String] options = case rtsOptions opt of [] -> args rtsopts -> args ++ ["+RTS"] ++ rtsopts ++ ["-RTS"] extractProcessID :: ProcessHandle -> IO ProcessID extractProcessID h = withProcessHandle h $ \x -> case x of OpenHandle pid -> return pid _ -> throwIO $ userError "Unable to retrieve child process ID." {- | create a new worker -} forkWorkerProcess :: (WorkerContext a) => a -- ^ a worker context -> IO ProcessID -- ^ a process id of a created worker forkWorkerProcess opt = forkWorkerProcessWithArgs opt []