module Control.Concurrent.Bag.ImplicitConcurrent
( module Control.Concurrent.Bag.Task
, newTaskBag
, newEvalBag
, newInterruptingBag
, newInterruptibleBag
, BufferType (..)
)
where
import Data.IORef
import Control.Monad.IO.Class
import qualified Control.Concurrent.Bag.Concurrent as Basic
import Control.Concurrent.Bag.Task
import System.IO.Unsafe (unsafeInterleaveIO)
import Control.Concurrent.Chan
import Control.Concurrent.Bag.TaskBuffer
newTaskBag :: BufferType
-> [TaskIO r (Maybe r)]
-> IO [r]
newTaskBag buf ts = do
bag <- Basic.newBag_ buf
mapM_ (\t -> Basic.addTask bag (runTaskIO t (Basic.addTask 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 :: BufferType
-> [r]
-> IO [r]
newEvalBag buf es =
newTaskBag buf (map (\e -> e `seq` return $ Just e) es)
newInterruptibleBag :: BufferType
-> [Interruptible r]
-> IO [r]
newInterruptibleBag buf ts = do
newTaskBag buf $ map runInterruptible ts
newInterruptingBag :: BufferType
-> [Interruptible r]
-> IO [r]
newInterruptingBag buf ts = do
newTaskBag buf $ map runInterrupted ts