-- Distributed Haskell: multithreading support -- -- Author : Manuel M T Chakravarty -- Duncan Coutts -- Created: 20 March 2000 -- -- Copyright (c) [2000..2003] Chakravarty & Coutts -- -- This file is free software; you can redistribute it and\/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This file is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- --- DESCRIPTION --------------------------------------------------------------- -- -- Some thread utility functions -- -- The form of the Fork-Join concurrency operator is taken from -- Arrows for Errors: extending the error monad -- http://www.coutts.uklinux.net/duncan/papers/ssafp02/ -- --- DOCU ---------------------------------------------------------------------- -- -- language: Haskell 98 + Concurrency -- -- Fork-Join concurrency operators -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- -- The type of the operators allows them to be chained like so: -- f &> x <&> y <&> z -- -- This will fork threads to evaluate x, y and z in parallel and return -- f applied to the results of x, y and z. -- --- TODO ---------------------------------------------------------------------- -- -- * Try implementation not based on throwTo module Control.Concurrent.ThreadUtils ( (<&>), (&>), (&), -- re-exported -- forkIO ) where import Prelude hiding (catch) import Control.Concurrent (myThreadId, newEmptyMVar, takeMVar, putMVar, forkIO) import Control.Exception (throwTo, catch) infixl 2 <&>, &>, & -- fork-join concurrency (EXPORTED) -- -- * exception safe: when any of the two threads terminates on an exception, -- it is guaranteed that the same exception is raised in the main thread -- (<&>) :: IO (a -> b) -> IO a -> IO b f <&> x = do mainId <- myThreadId xResVar <- newEmptyMVar forkIO $ (x >>= putMVar xResVar) `catch` throwTo mainId -- propagate exceptions fRes <- f xRes <- takeMVar xResVar return (fRes xRes) -- companion opertator to <&> (EXPORTED) -- (&>) :: (a -> b) -> (IO a -> IO b) f &> x = return f <&> x -- fork-join concurrency (compat) (EXPORTED) -- -- * compatibility with previous version of the Ports libary. -- Now a special case of the more general operator. -- (&) :: IO a -> IO b -> IO (a, b) m & n = (,) &> m <&> n