@@ -14,7 +14,7 @@ module Streamly.Internal.Data.Stream.StreamD.Exception
16 , bracket_
16 , bracket_
17− , bracket
17+ , bracket'
18 , onException
18 , onException
19 , finally_
19 , finally_
@@ -101,7 +101,9 @@ data GbracketIOState s1 s2 v wref
101-- output @c@ as input to @c -> Stream m b@ to generate an output stream. When
101-- output @c@ as input to @c -> Stream m b@ to generate an output stream. When
102-- generating the stream use the supplied @try@ operation @forall s. m s -> m
102-- generating the stream use the supplied @try@ operation @forall s. m s -> m
103-- (Either e s)@ to catch synchronous exceptions. If an exception occurs run
103-- (Either e s)@ to catch synchronous exceptions. If an exception occurs run
104−-- the exception handler @c -> e -> Stream m b -> m (Stream m b)@.
104+-- the exception handler @c -> e -> Stream m b -> m (Stream m b)@. Note that
105+-- 'gbracket' does not rethrow the exception, it has to be done by the
106+-- exception handler if desired.
106-- The cleanup action @c -> m d@, runs whenever the stream ends normally, due
108-- The cleanup action @c -> m d@, runs whenever the stream ends normally, due
107-- to a sync or async exception or if it gets garbage collected after a partial
109-- to a sync or async exception or if it gets garbage collected after a partial
@@ -115,13 +117,14 @@ data GbracketIOState s1 s2 v wref
115{-# INLINE_NORMAL gbracket #-}
117{-# INLINE_NORMAL gbracket #-}
117 :: (MonadIO m, MonadBaseControl IO m)
119 :: (MonadIO m, MonadBaseControl IO m)
118− => m c -- ^ before
120+ => m c -- ^ before
119− -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
121+ -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
122+ -> (c -> m d1) -- ^ on normal stop
120− -> (c -> m d) -- ^ after, on normal stop or GC
123+ -> (c -> m d2) -- ^ on GC without normal stop or exception
121 -> (c -> e -> Stream m b -> m (Stream m b)) -- ^ on exception
124 -> (c -> e -> Stream m b -> m (Stream m b)) -- ^ on exception
122− -> (c -> Stream m b) -- ^ stream generator
125+ -> (c -> Stream m b) -- ^ stream generator
123 -> Stream m b
126 -> Stream m b
124−gbracket bef exc aft fexc fnormal =
127+gbracket bef exc aft gc fexc fnormal =
125 Stream step GBracketIOInit
128 Stream step GBracketIOInit
@@ -137,7 +140,7 @@ gbracket bef exc aft fexc fnormal =
137 -- Tutorial: https://markkarpov.com/tutorial/exceptions.html
140 -- Tutorial: https://markkarpov.com/tutorial/exceptions.html
138 (r, ref) <- liftBaseOp_ mask_ $ do
141 (r, ref) <- liftBaseOp_ mask_ $ do
140− ref <- newIOFinalizer (aft r)
143+ ref <- newIOFinalizer (gc r)
141 return (r, ref)
144 return (r, ref)
142 return $ Skip $ GBracketIONormal (fnormal r) r ref
145 return $ Skip $ GBracketIONormal (fnormal r) r ref
@@ -149,9 +152,8 @@ gbracket bef exc aft fexc fnormal =
149 return $ Yield x (GBracketIONormal (Stream step1 s) v ref)
152 return $ Yield x (GBracketIONormal (Stream step1 s) v ref)
150 Skip s ->
153 Skip s ->
151 return $ Skip (GBracketIONormal (Stream step1 s) v ref)
154 return $ Skip (GBracketIONormal (Stream step1 s) v ref)
152− Stop -> do
155+ Stop ->
154− return Stop
156+ clearingIOFinalizer ref (aft v) >> return Stop
155 -- XXX Do not handle async exceptions, just rethrow them.
157 -- XXX Do not handle async exceptions, just rethrow them.
156 Left e -> do
158 Left e -> do
157 -- Clearing of finalizer and running of exception handler must
159 -- Clearing of finalizer and running of exception handler must
@@ -261,12 +263,17 @@ bracket_ bef aft bet =
262-- | See 'Streamly.Internal.Data.Stream.IsStream.bracket'.
264-- | See 'Streamly.Internal.Data.Stream.IsStream.bracket'.
264−{-# INLINE_NORMAL bracket #-}
266+{-# INLINE_NORMAL bracket' #-}
265−bracket :: (MonadAsync m, MonadCatch m)
267+bracket' :: (MonadAsync m, MonadCatch m) =>
272+ -> (b -> Stream m a)
266− => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
273+ -> Stream m a
267−bracket bef aft bet =
274+bracket' bef aft exc gc =
268− gbracket bef (inline MC.try) aft
275+ gbracket bef (inline MC.try) aft gc
269− (\a (e :: SomeException) _ -> aft a >> return (nilM (MC.throwM e))) bet
276+ (\a (e :: SomeException) _ -> exc a >> return (nilM (MC.throwM e)))
271data BracketState s v = BracketInit | BracketRun s v
278data BracketState s v = BracketInit | BracketRun s v
@@ -306,7 +313,8 @@ finally_ action xs = bracket_ (return ()) (\_ -> action) (const xs)
307{-# INLINE finally #-}
314{-# INLINE finally #-}
308finally :: (MonadAsync m, MonadCatch m) => m b -> Stream m a -> Stream m a
315finally :: (MonadAsync m, MonadCatch m) => m b -> Stream m a -> Stream m a
309−finally action xs = bracket (return ()) (\_ -> action) (const xs)
316+finally action xs = bracket' (return ()) act act act (const xs)
317+ where act _ = action
311-- | See 'Streamly.Internal.Data.Stream.IsStream.ghandle'.
319-- | See 'Streamly.Internal.Data.Stream.IsStream.ghandle'.