[commit: packages/unix] master: Fix `forkProcess` to inherit caller's `MaskingState` (897d66a)
git at git.haskell.org
git at git.haskell.org
Fri Nov 8 12:16:09 UTC 2013
Repository : ssh://git@git.haskell.org/unix
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/897d66ad9d77d17dae1b5ac94af792e671a76c13/unix
>---------------------------------------------------------------
commit 897d66ad9d77d17dae1b5ac94af792e671a76c13
Author: Herbert Valerio Riedel <hvr at gnu.org>
Date: Fri Nov 8 12:42:56 2013 +0100
Fix `forkProcess` to inherit caller's `MaskingState`
...and while at it, use `bracket` to fix a potential resource leak due
to `freeStablePtr` not being called if `throwErrnoIfMinus1` throws an
exception.
This fixes #8433
Signed-off-by: Herbert Valerio Riedel <hvr at gnu.org>
>---------------------------------------------------------------
897d66ad9d77d17dae1b5ac94af792e671a76c13
System/Posix/Process/Common.hsc | 22 ++++++++++++++++++----
changelog | 4 +++-
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/System/Posix/Process/Common.hsc b/System/Posix/Process/Common.hsc
index 51c75b3..1b504df 100644
--- a/System/Posix/Process/Common.hsc
+++ b/System/Posix/Process/Common.hsc
@@ -81,7 +81,9 @@ import System.Posix.Types
import Control.Monad
#ifdef __GLASGOW_HASKELL__
+import Control.Exception.Base ( bracket, getMaskingState, MaskingState(..) ) -- used by forkProcess
import GHC.TopHandler ( runIO )
+import GHC.IO ( unsafeUnmask, uninterruptibleMask_ )
#endif
#ifdef __HUGS__
@@ -278,6 +280,9 @@ threads will be copied to the child process.
On success, 'forkProcess' returns the child's 'ProcessID' to the parent process;
in case of an error, an exception is thrown.
+The exception masking state of the executed action is inherited
+(c.f. 'forkIO'), see also 'forkProcessWithUnmask' (/since: 2.7.0.0/).
+
'forkProcess' comes with a giant warning: since any other running
threads are not copied into the child process, it's easy to go wrong:
e.g. by accessing some shared resource that was held by another thread
@@ -286,10 +291,19 @@ in the parent.
forkProcess :: IO () -> IO ProcessID
forkProcess action = do
- stable <- newStablePtr (runIO action)
- pid <- throwErrnoIfMinus1 "forkProcess" (forkProcessPrim stable)
- freeStablePtr stable
- return pid
+ -- wrap action to re-establish caller's masking state, as
+ -- 'forkProcessPrim' starts in 'MaskedInterruptible' state by
+ -- default; see also #1048
+ mstate <- getMaskingState
+ let action' = case mstate of
+ Unmasked -> unsafeUnmask action
+ MaskedInterruptible -> action
+ MaskedUninterruptible -> uninterruptibleMask_ action
+
+ bracket
+ (newStablePtr (runIO action'))
+ freeStablePtr
+ (\stable -> throwErrnoIfMinus1 "forkProcess" (forkProcessPrim stable))
foreign import ccall "forkProcess" forkProcessPrim :: StablePtr (IO ()) -> IO CPid
#endif /* __GLASGOW_HASKELL__ */
diff --git a/changelog b/changelog
index 165cf82..ec0fbc8 100644
--- a/changelog
+++ b/changelog
@@ -1,6 +1,8 @@
-*-changelog-*-
-2.7.0.0 Oct 2013
+2.7.0.0 Nov 2013
+
+ * Change `forkProcess` to inherit the exception masking state of its caller
* Add new `Bool` flag to `ProcessStatus(Terminated)` constructor
indicating whether a core dump occured
More information about the ghc-commits
mailing list