[commit: packages/process] master: GH77: fix compile errors. (ae57e8c)
git at git.haskell.org
git at git.haskell.org
Wed Jul 19 21:18:06 UTC 2017
Repository : ssh://git@git.haskell.org/process
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/ae57e8c22b4e7f8356b1f21744add5b2f4d462b1/process
>---------------------------------------------------------------
commit ae57e8c22b4e7f8356b1f21744add5b2f4d462b1
Author: Tamar Christina <tamar at zhox.com>
Date: Mon Jan 2 20:30:50 2017 +0000
GH77: fix compile errors.
>---------------------------------------------------------------
ae57e8c22b4e7f8356b1f21744add5b2f4d462b1
System/Process/Windows.hsc | 29 +++++++++++++++++++++++++----
cbits/runProcess.c | 15 ++++++++++++---
include/runProcess.h | 5 ++++-
tests/T9775/T9775_good.hs | 8 ++------
4 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/System/Process/Windows.hsc b/System/Process/Windows.hsc
index b9c4eae..ff8d3a7 100644
--- a/System/Process/Windows.hsc
+++ b/System/Process/Windows.hsc
@@ -22,6 +22,7 @@ import System.Process.Common
import Control.Concurrent
import Control.Exception
import Data.Bits
+import Data.Maybe
import Foreign.C
import Foreign.Marshal
import Foreign.Ptr
@@ -197,14 +198,32 @@ waitForJobCompletion :: PHANDLE
-> CUInt
-> IO (Maybe CInt)
waitForJobCompletion job io timeout =
- alloca $ \p_exitCode -> do ret <- c_waitForJobCompletion job io timeout p_exitCode
- if ret == 0
- then Just <$> peek p_exitCode
- else return Nothing
+ alloca $ \p_exitCode -> do
+ items <- newMVar $ []
+ setter <- mkSetter (insertItem items)
+ getter <- mkGetter (getItem items)
+ ret <- c_waitForJobCompletion job io timeout p_exitCode setter getter
+ if ret == 0
+ then Just <$> peek p_exitCode
+ else return Nothing
+
+insertItem :: Eq k => MVar [(k, v)] -> k -> v -> IO ()
+insertItem env_ k v = modifyMVar_ env_ (return . ((k, v):))
+
+getItem :: Eq k => MVar [(k, v)] -> k -> IO v
+getItem env_ k = withMVar env_ (\m -> return $ fromJust $ lookup k m)
-- ----------------------------------------------------------------------------
-- Interface to C bits
+type SetterDef = CUInt -> Ptr () -> IO ()
+type GetterDef = CUInt -> IO (Ptr ())
+
+foreign import ccall "wrapper"
+ mkSetter :: SetterDef -> IO (FunPtr SetterDef)
+foreign import ccall "wrapper"
+ mkGetter :: GetterDef -> IO (FunPtr GetterDef)
+
foreign import WINDOWS_CCONV unsafe "TerminateJobObject"
c_terminateJobObject
:: PHANDLE
@@ -217,6 +236,8 @@ foreign import ccall interruptible "waitForJobCompletion" -- NB. safe - can bloc
-> PHANDLE
-> CUInt
-> Ptr CInt
+ -> FunPtr (SetterDef)
+ -> FunPtr (GetterDef)
-> IO CInt
foreign import ccall unsafe "runInteractiveProcess"
diff --git a/cbits/runProcess.c b/cbits/runProcess.c
index 43e3d7a..17463d6 100644
--- a/cbits/runProcess.c
+++ b/cbits/runProcess.c
@@ -792,8 +792,9 @@ waitForProcess (ProcHandle handle, int *pret)
return -1;
}
+
int
-waitForJobCompletion (HANDLE hJob, HANDLE ioPort, DWORD timeout, int *pExitCode)
+waitForJobCompletion ( HANDLE hJob, HANDLE ioPort, DWORD timeout, int *pExitCode, setterDef set, getterDef get )
{
DWORD CompletionCode;
ULONG_PTR CompletionKey;
@@ -813,15 +814,23 @@ waitForJobCompletion (HANDLE hJob, HANDLE ioPort, DWORD timeout, int *pExitCode)
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
+ {
// A new child process is born.
- break;
+ // Retrieve and save the process handle from the process id.
+ // We'll need it for later but we can't retrieve it after the
+ // process has exited.
+ DWORD pid = (DWORD)(uintptr_t)Overlapped;
+ HANDLE pHwnd = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, TRUE, pid);
+ set(pid, pHwnd);
+ }
+ break;
case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
case JOB_OBJECT_MSG_EXIT_PROCESS:
{
// A child process has just exited.
// Read exit code, We assume the last process to exit
// is the process whose exit code we're interested in.
- HANDLE pHwnd = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, TRUE, (DWORD)(uintptr_t)Overlapped);
+ HANDLE pHwnd = get((DWORD)(uintptr_t)Overlapped);
if (GetExitCodeProcess(pHwnd, (DWORD *)pExitCode) == 0)
{
maperrno();
diff --git a/include/runProcess.h b/include/runProcess.h
index 1662a62..3807389 100644
--- a/include/runProcess.h
+++ b/include/runProcess.h
@@ -85,8 +85,11 @@ extern ProcHandle runInteractiveProcess( wchar_t *cmd,
HANDLE *hJob,
HANDLE *hIOcpPort );
+typedef void(*setterDef)(DWORD, HANDLE);
+typedef HANDLE(*getterDef)(DWORD);
+
extern int terminateJob( ProcHandle handle );
-extern int waitForJobCompletion( HANDLE hJob, HANDLE ioPort, DWORD timeout, int *pExitCode );
+extern int waitForJobCompletion( HANDLE hJob, HANDLE ioPort, DWORD timeout, int *pExitCode, setterDef set, getterDef get );
#endif
diff --git a/tests/T9775/T9775_good.hs b/tests/T9775/T9775_good.hs
index 9461754..6634ad3 100644
--- a/tests/T9775/T9775_good.hs
+++ b/tests/T9775/T9775_good.hs
@@ -1,11 +1,7 @@
module Main where
import System.Process
-import System.Process.Internals
-import System.Exit
main
- = do (_,_,_,_,Just j,Just io) <- createProcessExt_ "T9775_good" True (proc "main" [])
- maybe (ExitFailure (-1)) mkExitCode <$> waitForJobCompletion j io timeout_Infinite >>= print
- where mkExitCode code | code == 0 = ExitSuccess
- | otherwise = ExitFailure $ fromIntegral code
+ = do (_,_,_,p) <- createProcess_ "T9775_good" (proc "main" []{ use_process_jobs = True })
+ waitForProcess p >>= print
More information about the ghc-commits
mailing list