module Control.Concurrent.Thread.Lifted (
fork
, forkOS
, forkOn
, forkWithUnmask
, forkOnWithUnmask
, Result
, result
) where
import Control.Concurrent (ThreadId)
import Control.Concurrent.Thread (Result)
import Control.Monad.Base
import Control.Monad.Trans.Control
import qualified Control.Concurrent.Thread as T
fork :: MonadBaseControl IO m
=> m a
-> m (ThreadId, m (Result a))
fork action = liftBaseWith $ \runInBase -> fixTypes
=<< T.forkIO (runInBase action)
forkOS :: MonadBaseControl IO m
=> m a
-> m (ThreadId, m (Result a))
forkOS action = liftBaseWith $ \runInBase -> fixTypes
=<< T.forkOS (runInBase action)
forkOn :: MonadBaseControl IO m
=> Int
-> m a
-> m (ThreadId, m (Result a))
forkOn i action = liftBaseWith $ \runInBase -> fixTypes
=<< T.forkOn i (runInBase action)
forkWithUnmask :: MonadBaseControl IO m
=> ((forall b. m b -> m b) -> m a)
-> m (ThreadId, m (Result a))
forkWithUnmask action = liftBaseWith $ \runInBase -> fixTypes
=<< T.forkIOWithUnmask (\unmask -> runInBase (action (liftBaseOp_ unmask)))
forkOnWithUnmask :: MonadBaseControl IO m
=> Int
-> ((forall b. m b -> m b) -> m a)
-> m (ThreadId, m (Result a))
forkOnWithUnmask i action = liftBaseWith $ \runInBase -> fixTypes
=<< T.forkOnWithUnmask i (\unmask -> runInBase (action (liftBaseOp_ unmask)))
result :: MonadBase IO m => Result a -> m a
result = liftBase . T.result
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)