spawn 0.2 → 0.3
raw patch · 4 files changed
+89/−7 lines, 4 files
Files
- Control/Concurrent/Spawn.hs +55/−3
- LICENSE +1/−1
- README +9/−0
- spawn.cabal +24/−3
Control/Concurrent/Spawn.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE+ CPP #-} module Control.Concurrent.Spawn ( -- * Spawn spawn@@ -5,12 +7,18 @@ -- * Spawn with @'try'@ , Result , spawnTry- ++ -- * Higher-level functions+ , parMapIO+ , parMapIO_+ , (|*|)+ -- * Limiting concurrency , pool ) where import Control.Concurrent import Control.Exception+import Control.Monad -- | Two ways a computation of type @'IO' a@ can end. type Result a = Either SomeException a@@ -18,14 +26,29 @@ -- | Spawn a concurrent computation. Produces an action which -- demands a @'Result'@. spawnTry :: IO a -> IO (IO (Result a))++-- We block asynchronous exceptions around 'forkIO', then restore+-- the parent thread's exception mask state inside 'try'. This+-- prevents an exception from interrupting 'putMVar', which would+-- deadlock the parent.+--+-- The API for doing this changed in base-4.3 with GHC 7.0.++#if MIN_VERSION_base(4,3,0) spawnTry m = do v <- newEmptyMVar- -- block async exns, then unblock inside 'try' unless parent was blocked- -- avoids dropping an exception+ _ <- mask $ \restore -> forkIO (try (restore m) >>= putMVar v)+ return (readMVar v)++#else+spawnTry m = do+ v <- newEmptyMVar b <- blocked _ <- block $ forkIO (try (if b then m else unblock m) >>= putMVar v) return (readMVar v) +#endif+ -- | Spawn a concurrent computation. Produces an action which -- demands the result. Any exception from the original computation -- is re-thrown when and where the result is demanded.@@ -34,6 +57,7 @@ r <- spawnTry m return (r >>= either throwIO return) + -- | Given /n/, produces a function to wrap @'IO'@ actions. -- No more than /n/ wrapped actions will be in progress at -- one time.@@ -41,3 +65,31 @@ pool n = do s <- newQSem n return $ bracket_ (waitQSem s) (signalQSem s)+++-- | Execute a separate thread of IO for each element of a list, and+-- collect results.+--+-- The analogy to @parMap@ is misleading. The concurrent execution+-- of these actions is non-deterministic and can affect results.+-- However, @'parMapIO'@ is expected to be most useful for actions+-- which do not interact.+parMapIO :: (a -> IO b) -> [a] -> IO [b]+parMapIO f xs = mapM (spawn . f) xs >>= sequence++-- | Execute a separate thread of IO for each element of a list.+--+-- Results are discarded, but the @'parMapIO_'@ action does not+-- complete until all threads have finished.+parMapIO_ :: (a -> IO b) -> [a] -> IO ()+parMapIO_ f xs = mapM (spawn . f) xs >>= sequence_+++infixl 4 |*|++-- | A concurrent version of @'ap'@ or @(\<*\>)@ for @'IO'@.+--+-- Spawns a thread for the right-hand action, while executing the+-- left-hand action in the current thread.+(|*|) :: IO (a -> b) -> IO a -> IO b+mf |*| mx = spawn mx >>= (mf `ap`)
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) Keegan McAllister 2010+Copyright (c) Keegan McAllister 2010, 2011 All rights reserved.
+ README view
@@ -0,0 +1,9 @@+spawn is a tiny Haskell library for concurrent computations.++Documentation is hosted at http://hackage.haskell.org/package/spawn++To build the documentation yourself, run++ $ cabal configure && cabal haddock --hyperlink-source++This will produce HTML documentation under dist/doc/html/spawn.
spawn.cabal view
@@ -1,19 +1,40 @@ name: spawn-version: 0.2+version: 0.3 license: BSD3 license-file: LICENSE-synopsis: Tiny library for joinable computations / threads with results.+synopsis: Tiny library for concurrent computations category: Concurrency, Concurrent, Control author: Keegan McAllister <mcallister.keegan@gmail.com> maintainer: Keegan McAllister <mcallister.keegan@gmail.com> build-type: Simple-cabal-version: >=1.2+cabal-version: >=1.6 description: Spawn a concurrent 'IO' computation and later demand its result. Tiny API and implementation.+ .+ New in version 0.3:+ .+ * Added functions @parMapIO@, @parMapIO_@, and @(|*|)@, which capture+ common use cases of @spawn@.+ .+ * Updated code to avoid using deprecated functions with @base-4.3@ and+ later (GHC 7.0 and later). The old code is still used with older+ @base@ libraries.+ .+ * Added public GitHub repository. +extra-source-files:+ README+ library exposed-modules: Control.Concurrent.Spawn ghc-options: -Wall build-depends: base >= 3 && < 5++ other-extensions:+ CPP++source-repository head+ type: git+ location: git://github.com/kmcallister/spawn.git