module Control.Concurrent.Thread.Group.Lifted (
TG.ThreadGroup
, new
, TG.nrOfRunning
, wait
, waitN
, fork
, forkOS
, forkOn
, forkWithUnmask
, forkOnWithUnmask
) where
import Control.Concurrent (ThreadId)
import Control.Concurrent.Thread (Result)
import Control.Monad.Base
import Control.Monad.Trans.Control
import qualified Control.Concurrent.Thread.Group as TG
new :: MonadBase IO m => m TG.ThreadGroup
new = liftBase TG.new
wait :: MonadBase IO m => TG.ThreadGroup -> m ()
wait = liftBase . TG.wait
waitN :: MonadBase IO m => Int -> TG.ThreadGroup -> m ()
waitN i = liftBase . TG.waitN i
fork :: MonadBaseControl IO m
=> TG.ThreadGroup
-> m a
-> m (ThreadId, m (Result a))
fork tg action = liftBaseWith $ \runInBase -> fixTypes
=<< TG.forkIO tg (runInBase action)
forkOS :: MonadBaseControl IO m
=> TG.ThreadGroup
-> m a
-> m (ThreadId, m (Result a))
forkOS tg action = liftBaseWith $ \runInBase -> fixTypes
=<< TG.forkOS tg (runInBase action)
forkOn :: MonadBaseControl IO m
=> Int
-> TG.ThreadGroup
-> m a
-> m (ThreadId, m (Result a))
forkOn i tg action = liftBaseWith $ \runInBase -> fixTypes
=<< TG.forkOn i tg (runInBase action)
forkWithUnmask :: MonadBaseControl IO m
=> TG.ThreadGroup
-> ((forall b. m b -> m b) -> m a)
-> m (ThreadId, m (Result a))
forkWithUnmask tg action = liftBaseWith $ \runInBase -> fixTypes
=<< TG.forkIOWithUnmask tg (\unmask -> runInBase (action (liftBaseOp_ unmask)))
forkOnWithUnmask :: MonadBaseControl IO m
=> Int
-> TG.ThreadGroup
-> ((forall b. m b -> m b) -> m a)
-> m (ThreadId, m (Result a))
forkOnWithUnmask i tg action = liftBaseWith $ \runInBase -> fixTypes
=<< TG.forkOnWithUnmask i tg (\unmask -> runInBase (action (liftBaseOp_ unmask)))
fixTypes :: MonadBaseControl IO m
=> (ThreadId, IO (Result (StM m a)))
-> IO (ThreadId, m (Result a))
fixTypes = return . fmap (\c -> liftBase c >>= mapMEither restoreM)
where
mapMEither :: Monad m => (a -> m b) -> Either c a -> m (Either c b)
mapMEither f (Right r) = f r >>= \v -> return (Right v)
mapMEither _ (Left v) = return (Left v)