on master help sign in
Mask async exceptions in the "bracketIO" functions.

Without this change, there are points (between "bef" and registration of "aft") at which async exceptions can cause resource leaks.

commit8f4f9ed2871187a57c3df44751a59bfeabcc3a78 authorShlok Datye <shlok@quant.is> dateSun 8 Mar 2020, 15:36 (7 years ago) parent18c903f
2 files changed+16−10
src/Streamly/Internal/Data/Stream/StreamD.hs+6−4 src/Streamly/Internal/Data/Unfold.hs+10−6
src/Streamly/Internal/Data/Stream/StreamD.hs+6−4
@@ -320,14 +320,14 @@ where
320320
321321import Control.Concurrent (killThread, myThreadId, takeMVar, threadDelay)
322322import Control.Exception
323− (Exception, SomeException, AsyncException, fromException)
323+ (Exception, SomeException, AsyncException, fromException, mask_)
324324import Control.Monad (void, when, forever)
325325import Control.Monad.Catch (MonadCatch, throwM)
326326import Control.Monad.IO.Class (MonadIO(..))
327327import Control.Monad.Reader (ReaderT)
328328import Control.Monad.State.Strict (StateT)
329329import Control.Monad.Trans (MonadTrans(lift))
330−import Control.Monad.Trans.Control (MonadBaseControl)
330+import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
331331import Data.Bits (shiftR, shiftL, (.|.), (.&.))
332332import Data.Functor.Identity (Identity(..))
333333import Data.Int (Int64)
@@ -2951,8 +2951,10 @@ gbracketIO bef exc aft fexc fnormal =
29512951 -- weak pointer to us.
29522952 {-# INLINE_LATE step #-}
29532953 step _ GBracketIOInit = do
2954− r <- bef
2955− ref <- newFinalizedIORef (aft r)
2954+ (r, ref) <- liftBaseOp_ mask_ $ do
2955+ r <- bef
2956+ ref <- newFinalizedIORef (aft r)
2957+ return (r, ref)
29562958 return $ Skip $ GBracketIONormal (fnormal r) r ref
29572959
29582960 step gst (GBracketIONormal (UnStream step1 st) v ref) = do
src/Streamly/Internal/Data/Unfold.hs+10−6
@@ -131,9 +131,9 @@ module Streamly.Internal.Data.Unfold
131131 )
132132where
133133
134−import Control.Exception (Exception)
134+import Control.Exception (Exception, mask_)
135135import Control.Monad.IO.Class (MonadIO(..))
136−import Control.Monad.Trans.Control (MonadBaseControl)
136+import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
137137import Data.Void (Void)
138138import GHC.Types (SPEC(..))
139139import Prelude
@@ -788,8 +788,10 @@ gbracketIO bef exc aft (Unfold estep einject) (Unfold step1 inject1) =
788788 where
789789
790790 inject x = do
791− r <- bef x
792− ref <- D.newFinalizedIORef (aft r)
791+ (r, ref) <- liftBaseOp_ mask_ $ do
792+ r <- bef x
793+ ref <- D.newFinalizedIORef (aft r)
794+ return (r, ref)
793795 s <- inject1 r
794796 return $ Right (s, r, ref)
795797
@@ -1038,9 +1040,11 @@ bracketIO bef aft (Unfold step1 inject1) = Unfold step inject
10381040 where
10391041
10401042 inject x = do
1041− r <- bef x
1043+ (r, ref) <- liftBaseOp_ mask_ $ do
1044+ r <- bef x
1045+ ref <- D.newFinalizedIORef (aft r)
1046+ return (r, ref)
10421047 s <- inject1 r
1043− ref <- D.newFinalizedIORef (aft r)
10441048 return (s, ref)
10451049
10461050 {-# INLINE_LATE step #-}