Repository : ssh://darcs.haskell.org//srv/darcs/packages/base On branch : master
http://hackage.haskell.org/trac/ghc/changeset/40d1be115d2a5a409e9b747c347cd909a9607c42 >--------------------------------------------------------------- commit 40d1be115d2a5a409e9b747c347cd909a9607c42 Author: Simon Marlow <[email protected]> Date: Thu Jun 7 16:10:47 2012 +0100 add forkFinally This is a more robust version of "forkIO (m `finally` k)", because it closes a window between thread creation and the finally where the thread can receive an async exception. Useful for layers over threads that need to catch threads dying with absolute certainty. forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId forkFinally action and_then = mask $ \restore -> forkIO $ try (restore action) >>= and_then >--------------------------------------------------------------- Control/Concurrent.hs | 27 +++++++++++++++++++++++---- 1 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Control/Concurrent.hs b/Control/Concurrent.hs index 770d9c3..1bac565 100644 --- a/Control/Concurrent.hs +++ b/Control/Concurrent.hs @@ -36,6 +36,7 @@ module Control.Concurrent ( forkIO, #ifdef __GLASGOW_HASKELL__ + forkFinally, forkIOWithUnmask, killThread, throwTo, @@ -205,6 +206,25 @@ Using Hugs, all I\/O operations and foreign calls will block all other Haskell threads. -} +-- | fork a thread and call the supplied function when the thread is about +-- to terminate, with an exception or a returned value. The function is +-- called with asynchronous exceptions masked. +-- +-- > forkFinally action and_then = +-- > mask $ \restore -> +-- > forkIO $ try (restore action) >>= and_then +-- +-- This function is useful for informing the parent when a child +-- terminates, for example. +-- +forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId +forkFinally action and_then = + mask $ \restore -> + forkIO $ try (restore action) >>= and_then + +-- ----------------------------------------------------------------------------- +-- Merging streams + #ifndef __HUGS__ max_buff_size :: Int max_buff_size = 1 @@ -598,11 +618,10 @@ foreign import ccall safe "fdReady" > myForkIO :: IO () -> IO (MVar ()) > myForkIO io = do > mvar <- newEmptyMVar -> forkIO (io `finally` putMVar mvar ()) +> forkFinally io (\_ -> putMVar mvar ()) > return mvar - Note that we use 'finally' from the - "Control.Exception" module to make sure that the + Note that we use 'forkFinally' to make sure that the 'MVar' is written to even if the thread dies or is killed for some reason. @@ -627,7 +646,7 @@ foreign import ccall safe "fdReady" > mvar <- newEmptyMVar > childs <- takeMVar children > putMVar children (mvar:childs) -> forkIO (io `finally` putMVar mvar ()) +> forkFinally io (\_ -> putMVar mvar ()) > > main = > later waitForChildren $ _______________________________________________ Cvs-libraries mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-libraries
