{-# LANGUAGE NoImplicitPrelude #-}
module Entwine.Data.Parallel (
Workers
, Result
, newResult
, emptyResult
, addResult
, getResult
, emptyWorkers
, failWorkers
, getWorkers
, addWorker
, waitForWorkers
, waitForWorkers'
) where
import Control.Concurrent.Async (Async, cancel, wait)
import Control.Concurrent.MVar
import Entwine.P
import System.IO
newtype Result a =
Result (MVar a)
newResult :: a -> IO (Result a)
newResult a =
Result <$> newMVar a
emptyResult :: IO (Result a)
emptyResult =
Result <$> newEmptyMVar
addResult :: Monad m => Result (m a) -> m a -> IO (m a)
addResult (Result r) w =
modifyMVar r (\x -> pure $ ((x >> w), x))
getResult :: Result a -> IO a
getResult (Result r) =
readMVar r
newtype Workers a =
Workers (MVar [Async a])
emptyWorkers :: IO (Workers a)
emptyWorkers =
Workers <$> newMVar []
failWorkers :: Workers a -> IO ()
failWorkers (Workers w) =
readMVar w >>=
mapM_ cancel
getWorkers :: Workers a -> IO [Async a]
getWorkers (Workers w) =
readMVar w
addWorker :: (Workers a) -> Async a -> IO ()
addWorker (Workers w) r =
modifyMVar_ w $ pure . (:) r
waitForWorkers :: (Workers a) -> IO ()
waitForWorkers (Workers w) =
readMVar w >>= mapM_ wait
waitForWorkers' :: (Workers a) -> IO [a]
waitForWorkers' (Workers w) =
readMVar w >>= mapM wait