@@ -149,15 +149,17 @@ import Control.Monad ((>=>), when)
149import Control.Monad.Catch (MonadCatch)
149import Control.Monad.Catch (MonadCatch)
150import Control.Monad.IO.Class (MonadIO(..))
150import Control.Monad.IO.Class (MonadIO(..))
151import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
151import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
152+import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef)
152import Data.Maybe (isNothing)
153import Data.Maybe (isNothing)
153import Data.Void (Void)
154import Data.Void (Void)
154−import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef)
155−import GHC.Types (SPEC(..))
156import Fusion.Plugin.Types (Fuse(..))
155import Fusion.Plugin.Types (Fuse(..))
157−import Streamly.Internal.Data.Stream.StreamD.Type (Stream(..), Step(..))
156+import GHC.Types (SPEC(..))
158−import Streamly.Internal.Data.Unfold.Types (Unfold(..))
159import Streamly.Internal.Data.Fold.Types (Fold(..))
157import Streamly.Internal.Data.Fold.Types (Fold(..))
158+import Streamly.Internal.Data.IOFinalizer
159+ (newIOFinalizer, runIOFinalizer, clearingIOFinalizer)
160+import Streamly.Internal.Data.Stream.StreamD.Type (Stream(..), Step(..))
160import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
161import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
162+import Streamly.Internal.Data.Unfold.Types (Unfold(..))
161import System.Mem (performMajorGC)
163import System.Mem (performMajorGC)
163import qualified Prelude
165import qualified Prelude
@@ -166,8 +168,7 @@ import qualified Data.Tuple as Tuple
166import qualified Streamly.Internal.Data.Fold.Types as FL
168import qualified Streamly.Internal.Data.Fold.Types as FL
167import qualified Streamly.Internal.Data.Stream.StreamK as K (uncons)
169import qualified Streamly.Internal.Data.Stream.StreamK as K (uncons)
168import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
170import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
169−import qualified Streamly.Internal.Data.Stream.StreamD as D
171+import qualified Streamly.Internal.Data.Stream.StreamD as D (unfold)
170− (unfold, newFinalizedIORef, runIORefFinalizer, withIORefFinalizer)
172import Streamly.Internal.Data.SVar
173import Streamly.Internal.Data.SVar
173import Prelude
174import Prelude
@@ -1154,7 +1155,7 @@ gbracket bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
1154 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1155 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1155 (r, ref) <- liftBaseOp_ mask_ $ do
1156 (r, ref) <- liftBaseOp_ mask_ $ do
1156 r <- bef x
1157 r <- bef x
1157− ref <- D.newFinalizedIORef (aft r)
1158+ ref <- newIOFinalizer (aft r)
1158 return (r, ref)
1159 return (r, ref)
1159 s <- inject1 r
1160 s <- inject1 r
1160 return $ Right (s, r, ref)
1161 return $ Right (s, r, ref)
@@ -1167,7 +1168,7 @@ gbracket bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
1167 Yield x s -> return $ Yield x (Right (s, v, ref))
1168 Yield x s -> return $ Yield x (Right (s, v, ref))
1168 Skip s -> return $ Skip (Right (s, v, ref))
1169 Skip s -> return $ Skip (Right (s, v, ref))
1169 Stop -> do
1170 Stop -> do
1170− D.runIORefFinalizer ref
1171+ runIOFinalizer ref
1171 return Stop
1172 return Stop
1172 -- XXX Do not handle async exceptions, just rethrow them.
1173 -- XXX Do not handle async exceptions, just rethrow them.
1173 Left e -> do
1174 Left e -> do
@@ -1175,7 +1176,7 @@ gbracket bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
1175 -- be atomic wrt async exceptions. Otherwise if we have cleared
1176 -- be atomic wrt async exceptions. Otherwise if we have cleared
1176 -- the finalizer and have not run the exception handler then we
1177 -- the finalizer and have not run the exception handler then we
1177 -- may leak the resource.
1178 -- may leak the resource.
1178− r <- D.withIORefFinalizer ref (einject (v, e))
1179+ r <- clearingIOFinalizer ref (einject (v, e))
1179 return $ Skip (Left r)
1180 return $ Skip (Left r)
1180 step (Left st) = do
1181 step (Left st) = do
1181 res <- estep st
1182 res <- estep st
@@ -1263,7 +1264,7 @@ after action (Unfold step1 inject1) = Unfold step inject
1264 inject x = do
1265 inject x = do
1265 s <- inject1 x
1266 s <- inject1 x
1266− ref <- D.newFinalizedIORef (action x)
1267+ ref <- newIOFinalizer (action x)
1267 return (s, ref)
1268 return (s, ref)
1269 {-# INLINE_LATE step #-}
1270 {-# INLINE_LATE step #-}
@@ -1273,7 +1274,7 @@ after action (Unfold step1 inject1) = Unfold step inject
1273 Yield x s -> return $ Yield x (s, ref)
1274 Yield x s -> return $ Yield x (s, ref)
1274 Skip s -> return $ Skip (s, ref)
1275 Skip s -> return $ Skip (s, ref)
1275 Stop -> do
1276 Stop -> do
1276− D.runIORefFinalizer ref
1277+ runIOFinalizer ref
1277 return Stop
1278 return Stop
1279{-# INLINE_NORMAL _onException #-}
1280{-# INLINE_NORMAL _onException #-}
@@ -1365,17 +1366,17 @@ finally action (Unfold step1 inject1) = Unfold step inject
1366 inject x = do
1367 inject x = do
1367 s <- inject1 x
1368 s <- inject1 x
1368− ref <- D.newFinalizedIORef (action x)
1369+ ref <- newIOFinalizer (action x)
1369 return (s, ref)
1370 return (s, ref)
1371 {-# INLINE_LATE step #-}
1372 {-# INLINE_LATE step #-}
1372 step (st, ref) = do
1373 step (st, ref) = do
1373− res <- step1 st `MC.onException` D.runIORefFinalizer ref
1374+ res <- step1 st `MC.onException` runIOFinalizer ref
1374 case res of
1375 case res of
1375 Yield x s -> return $ Yield x (s, ref)
1376 Yield x s -> return $ Yield x (s, ref)
1376 Skip s -> return $ Skip (s, ref)
1377 Skip s -> return $ Skip (s, ref)
1377 Stop -> do
1378 Stop -> do
1378− D.runIORefFinalizer ref
1379+ runIOFinalizer ref
1379 return Stop
1380 return Stop
1381{-# INLINE_NORMAL _bracket #-}
1382{-# INLINE_NORMAL _bracket #-}
@@ -1449,19 +1450,19 @@ bracket bef aft (Unfold step1 inject1) = Unfold step inject
1449 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1450 -- the registration of 'aft' atomic. See comment in 'D.gbracketIO'.
1450 (r, ref) <- liftBaseOp_ mask_ $ do
1451 (r, ref) <- liftBaseOp_ mask_ $ do
1451 r <- bef x
1452 r <- bef x
1452− ref <- D.newFinalizedIORef (aft r)
1453+ ref <- newIOFinalizer (aft r)
1453 return (r, ref)
1454 return (r, ref)
1454 s <- inject1 r
1455 s <- inject1 r
1455 return (s, ref)
1456 return (s, ref)
1457 {-# INLINE_LATE step #-}
1458 {-# INLINE_LATE step #-}
1458 step (st, ref) = do
1459 step (st, ref) = do
1459− res <- step1 st `MC.onException` D.runIORefFinalizer ref
1460+ res <- step1 st `MC.onException` runIOFinalizer ref
1460 case res of
1461 case res of
1461 Yield x s -> return $ Yield x (s, ref)
1462 Yield x s -> return $ Yield x (s, ref)
1462 Skip s -> return $ Skip (s, ref)
1463 Skip s -> return $ Skip (s, ref)
1463 Stop -> do
1464 Stop -> do
1464− D.runIORefFinalizer ref
1465+ runIOFinalizer ref
1465 return Stop
1466 return Stop
1467-- | When unfolding @Unfold m a b@ if an exception @e@ occurs, unfold @e@ using
1468-- | When unfolding @Unfold m a b@ if an exception @e@ occurs, unfold @e@ using