module Control.Concurrent.Bag.Implicit
( module Control.Concurrent.Bag.Task
, newTaskBag
, newEvalBag
, SplitFunction
, takeFirst
, splitVertical
, splitHalf
)
where
import Data.IORef
import Control.Monad.IO.Class
import qualified Control.Concurrent.Bag.Basic as Basic
import Control.Concurrent.Bag.Task
import Control.Concurrent.Bag.TaskBuffer
( TaskBufferSTM (..)
, SplitFunction
, takeFirst )
import System.IO.Unsafe (unsafeInterleaveIO)
newTaskBag :: (TaskBufferSTM b) =>
Maybe (SplitFunction b r)
-> [Task b r (Maybe r)]
-> IO [r]
newTaskBag split ts = do
bag <- Basic.newBag_ split
mapM_ (\t -> Basic.addTask bag (runTask t bag)) ts
Basic.noMoreTasks bag
dummy <- newIORef ()
_ <- mkWeakIORef dummy (Basic.terminateBag bag)
lazyResults bag dummy
where
lazyResults bag dummy = unsafeInterleaveIO $ do
r <- Basic.getResult bag
case r of
Nothing -> do
writeIORef dummy ()
return []
Just v -> do
vs <- lazyResults bag dummy
return (v:vs)
newEvalBag :: (TaskBufferSTM b) =>
Maybe (SplitFunction b r)
-> [r]
-> IO [r]
newEvalBag split es =
newTaskBag split (map (\e -> e `seq` return $ Just e) es)