@@ -1,5 +1,3 @@
1−{-# LANGUAGE UnboxedTuples #-}
4-- Module : Streamly.Internal.Control.Concurrent
2-- Module : Streamly.Internal.Control.Concurrent
5-- Copyright : (c) 2017 Composewell Technologies
3-- Copyright : (c) 2017 Composewell Technologies
@@ -7,29 +5,22 @@
7-- Maintainer : streamly@composewell.com
5-- Maintainer : streamly@composewell.com
8-- Stability : experimental
6-- Stability : experimental
9-- Portability : GHC
7-- Portability : GHC
9+-- Note: This module is primarily for abstractions related to MonadBaseControl.
10+-- Please do not add any general routines in this. It should be renamed
11module Streamly.Internal.Control.Concurrent
13module Streamly.Internal.Control.Concurrent
13 MonadAsync
15 MonadAsync
14 , RunInIO(..)
16 , RunInIO(..)
15 , captureMonadState
17 , captureMonadState
22−import Control.Concurrent (ThreadId, forkIO, killThread)
23−import Control.Exception (SomeException(..), catch, mask)
24import Control.Monad.Catch (MonadThrow)
21import Control.Monad.Catch (MonadThrow)
25import Control.Monad.IO.Class (MonadIO(..))
22import Control.Monad.IO.Class (MonadIO(..))
26−import Control.Monad.Trans.Control
23+import Control.Monad.Trans.Control (MonadBaseControl, control, StM)
27− (MonadBaseControl, control, StM, liftBaseDiscard)
28−import Data.Functor (void)
29−import GHC.Conc (ThreadId(..))
31−import GHC.IO (IO(..))
32−import System.Mem.Weak (addFinalizer)
34-- /Since: 0.8.0 ("Streamly.Prelude")/
25-- /Since: 0.8.0 ("Streamly.Prelude")/
@@ -53,48 +44,3 @@ newtype RunInIO m = RunInIO { runInIO :: forall b. m b -> IO (StM m b) }
53-- execution.
44-- execution.
54captureMonadState :: MonadBaseControl IO m => m (RunInIO m)
45captureMonadState :: MonadBaseControl IO m => m (RunInIO m)
55captureMonadState = control $ \run -> run (return $ RunInIO run)
46captureMonadState = control $ \run -> run (return $ RunInIO run)
57−-- Stolen from the async package. The perf improvement is modest, 2% on a
58−-- thread heavy benchmark (parallel composition using noop computations).
59−-- A version of forkIO that does not include the outer exception
60−-- handler: saves a bit of time when we will be installing our own
62−{-# INLINE rawForkIO #-}
63−rawForkIO :: IO () -> IO ThreadId
64−rawForkIO (IO action) = IO $ \ s ->
65− case fork# action s of (# s1, tid #) -> (# s1, ThreadId tid #)
67−-- | Fork a thread to run the given computation, installing the provided
68−-- exception handler. Lifted to any monad with 'MonadBaseControl IO m'
71−-- TODO: the RunInIO argument can be removed, we can directly pass the action
72−-- as "mrun action" instead.
74−doFork :: MonadBaseControl IO m
77− -> (SomeException -> IO ())
79−doFork action (RunInIO mrun) exHandler =
81− mask $ \restore -> do
82− tid <- rawForkIO $ catch (restore $ void $ mrun action)
86−-- | 'fork' lifted to any monad with 'MonadBaseControl IO m' capability.
88−{-# INLINABLE fork #-}
89−fork :: MonadBaseControl IO m => m () -> m ThreadId
90−fork = liftBaseDiscard forkIO
92−-- | Fork a thread that is automatically killed as soon as the reference to the
93−-- returned threadId is garbage collected.
95−{-# INLINABLE forkManaged #-}
96−forkManaged :: (MonadIO m, MonadBaseControl IO m) => m () -> m ThreadId
97−forkManaged action = do
99− liftIO $ addFinalizer tid (killThread tid)