@@ -1,5 +1,3 @@
1−#include "inline.hs"
2−
31-- |
42-- Module : Streamly.Internal.Data.Unfold
53-- Copyright : (c) 2019 Composewell Technologies
@@ -250,13 +248,13 @@ module Streamly.Internal.Data.Unfold
250248
251249 -- ** Resource Management
252250 , gbracket_
253− , gbracket
251+ , gbracketIO
254252 , before
255− , after
253+ , afterIO
256254 , after_
257− , finally
255+ , finallyIO
258256 , finally_
259− , bracket
257+ , bracketIO
260258 , bracket_
261259
262260 -- ** Exceptions
@@ -265,13 +263,13 @@ module Streamly.Internal.Data.Unfold
265263 )
266264where
267265
266+#include "inline.hs"
268267#include "ArrayMacros.h"
269268
270269import Control.Exception (Exception, mask_)
271270import Control.Monad.Catch (MonadCatch)
272271import Data.Functor (($>))
273272import GHC.Types (SPEC(..))
274−import Streamly.Internal.Control.Concurrent (MonadRunInIO, MonadAsync, withRunInIO)
275273import Streamly.Internal.Data.Fold.Type (Fold(..))
276274import Streamly.Internal.Data.IOFinalizer
277275 (newIOFinalizer, runIOFinalizer, clearingIOFinalizer)
@@ -846,12 +844,11 @@ dropWhile f = dropWhileM (return . f)
846844-- Exceptions
847845------------------------------------------------------------------------------
848846
849−-- | Like 'gbracket' but with following differences:
847+-- | Like 'gbracketIO' but with following differences:
850848--
851849-- * alloc action @a -> m c@ runs with async exceptions enabled
852850-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
853851-- after partial evaluation.
854−-- * does not require a 'MonadAsync' constraint.
855852--
856853-- /Inhibits stream fusion/
857854--
@@ -911,16 +908,17 @@ gbracket_ bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
911908-- /Inhibits stream fusion/
912909--
913910-- /Pre-release/
914−{-# INLINE_NORMAL gbracket #-}
915−gbracket
916− :: MonadRunInIO m
917− => (a -> m c) -- ^ before
918− -> (c -> m d) -- ^ after, on normal stop, or GC
919− -> Unfold m (c, e) b -- ^ on exception
920− -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
911+{-# INLINE_NORMAL gbracketIO #-}
912+gbracketIO
913+ :: MonadIO m
914+ => (a -> IO c) -- ^ before
915+ -> (c -> IO d) -- ^ after, on normal stop, or GC
916+ -> (c -> IO ()) -- ^ action on exception
917+ -> Unfold m e b -- ^ stream on exception
918+ -> (forall s. m s -> IO (Either e s)) -- ^ try (exception handling)
921919 -> Unfold m c b -- ^ unfold to run
922920 -> Unfold m a b
923−gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
921+gbracketIO bef aft onExc (Unfold estep einject) ftry (Unfold step1 inject1) =
924922 Unfold step inject
925923
926924 where
@@ -928,7 +926,7 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
928926 inject x = do
929927 -- Mask asynchronous exceptions to make the execution of 'bef' and
930928 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
931− (r, ref) <- withRunInIO $ \run -> mask_ $ run $ do
929+ (r, ref) <- liftIO $ mask_ $ do
932930 r <- bef x
933931 ref <- newIOFinalizer (aft r)
934932 return (r, ref)
@@ -937,7 +935,7 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
937935
938936 {-# INLINE_LATE step #-}
939937 step (Right (st, v, ref)) = do
940− res <- ftry $ step1 st
938+ res <- liftIO $ ftry $ step1 st
941939 case res of
942940 Right r -> case r of
943941 Yield x s -> return $ Yield x (Right (s, v, ref))
@@ -951,7 +949,8 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
951949 -- be atomic wrt async exceptions. Otherwise if we have cleared
952950 -- the finalizer and have not run the exception handler then we
953951 -- may leak the resource.
954− r <- clearingIOFinalizer ref (einject (v, e))
952+ liftIO $ clearingIOFinalizer ref (onExc v)
953+ r <- einject e
955954 return $ Skip (Left r)
956955 step (Left st) = do
957956 res <- estep st
@@ -1013,16 +1012,16 @@ after_ action (Unfold step1 inject1) = Unfold step inject
10131012-- /See also 'after_'/
10141013--
10151014-- /Pre-release/
1016−{-# INLINE_NORMAL after #-}
1017−after :: MonadRunInIO m
1018− => (a -> m c) -> Unfold m a b -> Unfold m a b
1019−after action (Unfold step1 inject1) = Unfold step inject
1015+{-# INLINE_NORMAL afterIO #-}
1016+afterIO :: MonadIO m
1017+ => (a -> IO c) -> Unfold m a b -> Unfold m a b
1018+afterIO action (Unfold step1 inject1) = Unfold step inject
10201019
10211020 where
10221021
10231022 inject x = do
10241023 s <- inject1 x
1025− ref <- newIOFinalizer (action x)
1024+ ref <- liftIO $ newIOFinalizer (action x)
10261025 return (s, ref)
10271026
10281027 {-# INLINE_LATE step #-}
@@ -1072,11 +1071,10 @@ _finally action =
10721071 gbracket_ return MC.try action
10731072 (nilM (\(a, e :: MC.SomeException) -> action a >> MC.throwM e))
10741073
1075−-- | Like 'finally' with following differences:
1074+-- | Like 'finallyIO' with following differences:
10761075--
10771076-- * action @a -> m c@ won't run if the stream is garbage collected
10781077-- after partial evaluation.
1079−-- * does not require a 'MonadAsync' constraint.
10801078--
10811079-- /Inhibits stream fusion/
10821080--
@@ -1115,16 +1113,16 @@ finally_ action (Unfold step1 inject1) = Unfold step inject
11151113-- /Inhibits stream fusion/
11161114--
11171115-- /Pre-release/
1118−{-# INLINE_NORMAL finally #-}
1119−finally :: (MonadAsync m, MonadCatch m)
1120− => (a -> m c) -> Unfold m a b -> Unfold m a b
1121−finally action (Unfold step1 inject1) = Unfold step inject
1116+{-# INLINE_NORMAL finallyIO #-}
1117+finallyIO :: (MonadIO m, MonadCatch m)
1118+ => (a -> IO c) -> Unfold m a b -> Unfold m a b
1119+finallyIO action (Unfold step1 inject1) = Unfold step inject
11221120
11231121 where
11241122
11251123 inject x = do
11261124 s <- inject1 x
1127− ref <- newIOFinalizer (action x)
1125+ ref <- liftIO $ newIOFinalizer (action x)
11281126 return (s, ref)
11291127
11301128 {-# INLINE_LATE step #-}
@@ -1144,12 +1142,11 @@ _bracket bef aft =
11441142 gbracket_ bef MC.try aft (nilM (\(a, e :: MC.SomeException) -> aft a >>
11451143 MC.throwM e))
11461144
1147−-- | Like 'bracket' but with following differences:
1145+-- | Like 'bracketIO' but with following differences:
11481146--
11491147-- * alloc action @a -> m c@ runs with async exceptions enabled
11501148-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
11511149-- after partial evaluation.
1152−-- * does not require a 'MonadAsync' constraint.
11531150--
11541151-- /Inhibits stream fusion/
11551152--
@@ -1196,17 +1193,17 @@ bracket_ bef aft (Unfold step1 inject1) = Unfold step inject
11961193-- /Inhibits stream fusion/
11971194--
11981195-- /Pre-release/
1199−{-# INLINE_NORMAL bracket #-}
1200−bracket :: (MonadAsync m, MonadCatch m)
1201− => (a -> m c) -> (c -> m d) -> Unfold m c b -> Unfold m a b
1202−bracket bef aft (Unfold step1 inject1) = Unfold step inject
1196+{-# INLINE_NORMAL bracketIO #-}
1197+bracketIO :: (MonadIO m, MonadCatch m)
1198+ => (a -> IO c) -> (c -> IO d) -> Unfold m c b -> Unfold m a b
1199+bracketIO bef aft (Unfold step1 inject1) = Unfold step inject
12031200
12041201 where
12051202
12061203 inject x = do
12071204 -- Mask asynchronous exceptions to make the execution of 'bef' and
12081205 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1209− (r, ref) <- withRunInIO $ \run -> mask_ $ run $ do
1206+ (r, ref) <- liftIO $ mask_ $ do
12101207 r <- bef x
12111208 ref <- newIOFinalizer (aft r)
12121209 return (r, ref)