@@ -1,5 +1,3 @@
4-- Module : Streamly.Internal.Data.Unfold
2-- Module : Streamly.Internal.Data.Unfold
5-- Copyright : (c) 2019 Composewell Technologies
3-- Copyright : (c) 2019 Composewell Technologies
@@ -250,13 +248,13 @@ module Streamly.Internal.Data.Unfold
251 -- ** Resource Management
249 -- ** Resource Management
252 , gbracket_
250 , gbracket_
253− , gbracket
251+ , gbracketIO
255− , after
253+ , afterIO
257− , finally
255+ , finallyIO
258 , finally_
256 , finally_
259− , bracket
257+ , bracketIO
260 , bracket_
258 , bracket_
262 -- ** Exceptions
260 -- ** Exceptions
@@ -265,13 +263,13 @@ module Streamly.Internal.Data.Unfold
268#include "ArrayMacros.h"
267#include "ArrayMacros.h"
270import Control.Exception (Exception, mask_)
269import Control.Exception (Exception, mask_)
271import Control.Monad.Catch (MonadCatch)
270import Control.Monad.Catch (MonadCatch)
272import Data.Functor (($>))
271import Data.Functor (($>))
273import GHC.Types (SPEC(..))
272import GHC.Types (SPEC(..))
274−import Streamly.Internal.Control.Concurrent (MonadRunInIO, MonadAsync, withRunInIO)
275import Streamly.Internal.Data.Fold.Type (Fold(..))
273import Streamly.Internal.Data.Fold.Type (Fold(..))
276import Streamly.Internal.Data.IOFinalizer
274import Streamly.Internal.Data.IOFinalizer
277 (newIOFinalizer, runIOFinalizer, clearingIOFinalizer)
275 (newIOFinalizer, runIOFinalizer, clearingIOFinalizer)
@@ -846,12 +844,11 @@ dropWhile f = dropWhileM (return . f)
846-- Exceptions
844-- Exceptions
847------------------------------------------------------------------------------
845------------------------------------------------------------------------------
849−-- | Like 'gbracket' but with following differences:
847+-- | Like 'gbracketIO' but with following differences:
851-- * alloc action @a -> m c@ runs with async exceptions enabled
849-- * alloc action @a -> m c@ runs with async exceptions enabled
852-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
850-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
853-- after partial evaluation.
851-- after partial evaluation.
854−-- * does not require a 'MonadAsync' constraint.
856-- /Inhibits stream fusion/
853-- /Inhibits stream fusion/
@@ -911,16 +908,17 @@ gbracket_ bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
911-- /Inhibits stream fusion/
908-- /Inhibits stream fusion/
913-- /Pre-release/
910-- /Pre-release/
914−{-# INLINE_NORMAL gbracket #-}
911+{-# INLINE_NORMAL gbracketIO #-}
915−gbracket
912+gbracketIO
916− :: MonadRunInIO m
913+ :: MonadIO m
917− => (a -> m c) -- ^ before
914+ => (a -> IO c) -- ^ before
918− -> (c -> m d) -- ^ after, on normal stop, or GC
915+ -> (c -> IO d) -- ^ after, on normal stop, or GC
916+ -> (c -> IO ()) -- ^ action on exception
919− -> Unfold m (c, e) b -- ^ on exception
917+ -> Unfold m e b -- ^ stream on exception
920− -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
918+ -> (forall s. m s -> IO (Either e s)) -- ^ try (exception handling)
921 -> Unfold m c b -- ^ unfold to run
919 -> Unfold m c b -- ^ unfold to run
922 -> Unfold m a b
920 -> 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) =
924 Unfold step inject
922 Unfold step inject
@@ -928,7 +926,7 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
928 inject x = do
926 inject x = do
929 -- Mask asynchronous exceptions to make the execution of 'bef' and
927 -- Mask asynchronous exceptions to make the execution of 'bef' and
930 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
928 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
931− (r, ref) <- withRunInIO $ \run -> mask_ $ run $ do
929+ (r, ref) <- liftIO $ mask_ $ do
932 r <- bef x
930 r <- bef x
933 ref <- newIOFinalizer (aft r)
931 ref <- newIOFinalizer (aft r)
934 return (r, ref)
932 return (r, ref)
@@ -937,7 +935,7 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
938 {-# INLINE_LATE step #-}
936 {-# INLINE_LATE step #-}
939 step (Right (st, v, ref)) = do
937 step (Right (st, v, ref)) = do
940− res <- ftry $ step1 st
938+ res <- liftIO $ ftry $ step1 st
941 case res of
939 case res of
942 Right r -> case r of
940 Right r -> case r of
943 Yield x s -> return $ Yield x (Right (s, v, ref))
941 Yield x s -> return $ Yield x (Right (s, v, ref))
@@ -951,7 +949,8 @@ gbracket bef aft (Unfold estep einject) ftry (Unfold step1 inject1) =
951 -- be atomic wrt async exceptions. Otherwise if we have cleared
949 -- be atomic wrt async exceptions. Otherwise if we have cleared
952 -- the finalizer and have not run the exception handler then we
950 -- the finalizer and have not run the exception handler then we
953 -- may leak the resource.
951 -- may leak the resource.
952+ liftIO $ clearingIOFinalizer ref (onExc v)
954− r <- clearingIOFinalizer ref (einject (v, e))
953+ r <- einject e
955 return $ Skip (Left r)
954 return $ Skip (Left r)
956 step (Left st) = do
955 step (Left st) = do
957 res <- estep st
956 res <- estep st
@@ -1013,16 +1012,16 @@ after_ action (Unfold step1 inject1) = Unfold step inject
1013-- /See also 'after_'/
1012-- /See also 'after_'/
1015-- /Pre-release/
1014-- /Pre-release/
1016−{-# INLINE_NORMAL after #-}
1015+{-# INLINE_NORMAL afterIO #-}
1017−after :: MonadRunInIO m
1016+afterIO :: MonadIO m
1018− => (a -> m c) -> Unfold m a b -> Unfold m a b
1017+ => (a -> IO c) -> Unfold m a b -> Unfold m a b
1019−after action (Unfold step1 inject1) = Unfold step inject
1018+afterIO action (Unfold step1 inject1) = Unfold step inject
1023 inject x = do
1022 inject x = do
1024 s <- inject1 x
1023 s <- inject1 x
1025− ref <- newIOFinalizer (action x)
1024+ ref <- liftIO $ newIOFinalizer (action x)
1026 return (s, ref)
1025 return (s, ref)
1028 {-# INLINE_LATE step #-}
1027 {-# INLINE_LATE step #-}
@@ -1072,11 +1071,10 @@ _finally action =
1072 gbracket_ return MC.try action
1071 gbracket_ return MC.try action
1073 (nilM (\(a, e :: MC.SomeException) -> action a >> MC.throwM e))
1072 (nilM (\(a, e :: MC.SomeException) -> action a >> MC.throwM e))
1075−-- | Like 'finally' with following differences:
1074+-- | Like 'finallyIO' with following differences:
1077-- * action @a -> m c@ won't run if the stream is garbage collected
1076-- * action @a -> m c@ won't run if the stream is garbage collected
1078-- after partial evaluation.
1077-- after partial evaluation.
1079−-- * does not require a 'MonadAsync' constraint.
1081-- /Inhibits stream fusion/
1079-- /Inhibits stream fusion/
@@ -1115,16 +1113,16 @@ finally_ action (Unfold step1 inject1) = Unfold step inject
1115-- /Inhibits stream fusion/
1113-- /Inhibits stream fusion/
1117-- /Pre-release/
1115-- /Pre-release/
1118−{-# INLINE_NORMAL finally #-}
1116+{-# INLINE_NORMAL finallyIO #-}
1119−finally :: (MonadAsync m, MonadCatch m)
1117+finallyIO :: (MonadIO m, MonadCatch m)
1120− => (a -> m c) -> Unfold m a b -> Unfold m a b
1118+ => (a -> IO c) -> Unfold m a b -> Unfold m a b
1121−finally action (Unfold step1 inject1) = Unfold step inject
1119+finallyIO action (Unfold step1 inject1) = Unfold step inject
1125 inject x = do
1123 inject x = do
1126 s <- inject1 x
1124 s <- inject1 x
1127− ref <- newIOFinalizer (action x)
1125+ ref <- liftIO $ newIOFinalizer (action x)
1128 return (s, ref)
1126 return (s, ref)
1130 {-# INLINE_LATE step #-}
1128 {-# INLINE_LATE step #-}
@@ -1144,12 +1142,11 @@ _bracket bef aft =
1144 gbracket_ bef MC.try aft (nilM (\(a, e :: MC.SomeException) -> aft a >>
1142 gbracket_ bef MC.try aft (nilM (\(a, e :: MC.SomeException) -> aft a >>
1145 MC.throwM e))
1143 MC.throwM e))
1147−-- | Like 'bracket' but with following differences:
1145+-- | Like 'bracketIO' but with following differences:
1149-- * alloc action @a -> m c@ runs with async exceptions enabled
1147-- * alloc action @a -> m c@ runs with async exceptions enabled
1150-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
1148-- * cleanup action @c -> m d@ won't run if the stream is garbage collected
1151-- after partial evaluation.
1149-- after partial evaluation.
1152−-- * does not require a 'MonadAsync' constraint.
1154-- /Inhibits stream fusion/
1151-- /Inhibits stream fusion/
@@ -1196,17 +1193,17 @@ bracket_ bef aft (Unfold step1 inject1) = Unfold step inject
1196-- /Inhibits stream fusion/
1193-- /Inhibits stream fusion/
1198-- /Pre-release/
1195-- /Pre-release/
1199−{-# INLINE_NORMAL bracket #-}
1196+{-# INLINE_NORMAL bracketIO #-}
1200−bracket :: (MonadAsync m, MonadCatch m)
1197+bracketIO :: (MonadIO m, MonadCatch m)
1201− => (a -> m c) -> (c -> m d) -> Unfold m c b -> Unfold m a b
1198+ => (a -> IO c) -> (c -> IO d) -> Unfold m c b -> Unfold m a b
1202−bracket bef aft (Unfold step1 inject1) = Unfold step inject
1199+bracketIO bef aft (Unfold step1 inject1) = Unfold step inject
1206 inject x = do
1203 inject x = do
1207 -- Mask asynchronous exceptions to make the execution of 'bef' and
1204 -- Mask asynchronous exceptions to make the execution of 'bef' and
1208 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1205 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1209− (r, ref) <- withRunInIO $ \run -> mask_ $ run $ do
1206+ (r, ref) <- liftIO $ mask_ $ do
1210 r <- bef x
1207 r <- bef x
1211 ref <- newIOFinalizer (aft r)
1208 ref <- newIOFinalizer (aft r)
1212 return (r, ref)
1209 return (r, ref)