streamly-0.8.2: src/Streamly/Internal/Control/ForkLifted.hs
-- |
-- Module : Streamly.Internal.Control.ForkLifted
-- Copyright : (c) 2017 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
module Streamly.Internal.Control.ForkLifted
(
doFork
, fork
, forkManaged
)
where
import Control.Concurrent (ThreadId, forkIO)
import Control.Exception (SomeException(..), catch, mask)
import Data.Functor (void)
import Streamly.Internal.Control.Concurrent (MonadRunInIO, RunInIO(..), withRunInIO, withRunInIONoRestore)
import Streamly.Internal.Control.ForkIO (rawForkIO, forkManagedWith)
-- | Fork a thread to run the given computation, installing the provided
-- exception handler. Lifted to any monad with 'MonadRunInIO m'
-- capability.
--
-- TODO: the RunInIO argument can be removed, we can directly pass the action
-- as "mrun action" instead.
{-# INLINE doFork #-}
doFork :: MonadRunInIO m
=> m ()
-> RunInIO m
-> (SomeException -> IO ())
-> m ThreadId
doFork action (RunInIO mrun) exHandler =
withRunInIO $ \run ->
mask $ \restore -> do
tid <- rawForkIO $ catch (restore $ void $ mrun action)
exHandler
run (return tid)
-- | 'fork' lifted to any monad with 'MonadBaseControl IO m' capability.
--
{-# INLINABLE fork #-}
fork :: MonadRunInIO m => m () -> m ThreadId
fork m = withRunInIONoRestore $ \run -> forkIO $ void $ run m
-- | Fork a thread that is automatically killed as soon as the reference to the
-- returned threadId is garbage collected.
--
{-# INLINABLE forkManaged #-}
forkManaged :: MonadRunInIO m => m () -> m ThreadId
forkManaged = forkManagedWith fork