{-# LANGUAGE BlockArguments #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-} module Context.Concurrent ( -- * Introduction -- $intro -- * Control.Concurrent wrappers forkIO , forkFinally , forkIOWithUnmask , forkOn , forkOnWithUnmask , forkOS , forkOSWithUnmask , runInBoundThread , runInUnboundThread -- * Control.Concurrent re-exports , ThreadId , myThreadId , killThread , throwTo , getNumCapabilities , setNumCapabilities , threadCapability , yield , threadDelay , threadWaitRead , threadWaitWrite , threadWaitReadSTM , threadWaitWriteSTM , rtsSupportsBoundThreads , isCurrentThreadBound , mkWeakThreadId , module Control.Concurrent.MVar , module Control.Concurrent.Chan , module Control.Concurrent.QSem , module Control.Concurrent.QSemN ) where import Control.Concurrent ( ThreadId, getNumCapabilities, isCurrentThreadBound, killThread, mkWeakThreadId, myThreadId , rtsSupportsBoundThreads, setNumCapabilities, threadCapability, threadDelay, threadWaitRead , threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, throwTo, yield ) import Control.Concurrent.Chan import Control.Concurrent.MVar import Control.Concurrent.QSem import Control.Concurrent.QSemN import Control.Exception (SomeException) import Prelude import qualified Context.Internal as Internal import qualified Control.Concurrent as Concurrent import qualified Control.Exception as Exception -- | See 'Concurrent.forkIO'. -- -- @since 0.1.0.0 forkIO :: IO () -> IO ThreadId forkIO action = do Internal.withPropagator \propagate -> do Concurrent.forkIO $ propagate action -- | See 'Concurrent.forkFinally'. -- -- @since 0.1.0.0 forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId forkFinally action and_then = do -- N.B. We re-implement forkFinally instead of delegating directly to the -- Control.Concurrent function. This enables us to propagate context a single -- time to make it available to both the thread's main action and terminating -- action. Internal.withPropagator \propagate -> do Exception.mask \restore -> do Concurrent.forkIO $ propagate do Exception.try (restore action) >>= and_then -- | See 'Concurrent.forkIOWithUnmask'. -- -- @since 0.1.0.0 forkIOWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId forkIOWithUnmask io = do Internal.withPropagator \propagate -> do Concurrent.forkIOWithUnmask \restore -> do propagate $ io restore -- | See 'Concurrent.forkOn'. -- -- @since 0.1.0.0 forkOn :: Int -> IO () -> IO ThreadId forkOn cpu action = do Internal.withPropagator \propagate -> do Concurrent.forkOn cpu $ propagate action -- | See 'Concurrent.forkOnWithUnmask'. -- -- @since 0.1.0.0 forkOnWithUnmask :: Int -> ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId forkOnWithUnmask cpu io = do Internal.withPropagator \propagate -> do Concurrent.forkOnWithUnmask cpu \restore -> do propagate $ io restore -- | See 'Concurrent.forkOS'. -- -- @since 0.1.0.0 forkOS :: IO () -> IO ThreadId forkOS action = do Internal.withPropagator \propagate -> do Concurrent.forkOS $ propagate action -- | See 'Concurrent.forkOSWithUnmask'. -- -- @since 0.1.0.0 forkOSWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId forkOSWithUnmask io = do Internal.withPropagator \propagate -> do Concurrent.forkOSWithUnmask \restore -> do propagate $ io restore -- | See 'Concurrent.runInBoundThread'. -- -- @since 0.1.0.0 runInBoundThread :: IO a -> IO a runInBoundThread action = Internal.withPropagator \propagate -> do Concurrent.runInBoundThread $ propagate action -- | See 'Concurrent.runInUnboundThread'. -- -- @since 0.1.0.0 runInUnboundThread :: IO a -> IO a runInUnboundThread action = Internal.withPropagator \propagate -> do Concurrent.runInUnboundThread $ propagate action -- $intro -- -- This module provides a "Context"-compatible interface around -- "Control.Concurrent". Depending on the 'Context.Storage.PropagationStrategy' -- of the 'Context.Store', the @fork*@ and @run*@ functions in this module can -- automatically propagate the calling thread's latest registered contexts, if -- any, over so that they are also available to the thread being created. -- -- This module is designed to be a drop-in replacement for "Control.Concurrent" so -- that users only have to import this module instead of both this module and -- "Control.Concurrent". It is also re-exported from "Context" for convenience.