on master help sign in
Fix atomicity issue when running a finalizer
a54a1aeHarendra Kumar
Changelog.md+2−1
@@ -20,7 +20,8 @@
20 API in `Streamly.Network.Socket` now close the socket if an exception is
20 API in `Streamly.Network.Socket` now close the socket if an exception is
21 thrown.
21 thrown.
22* `bracket`, `handle`, and `finally` now work on streams that aren't
22* `bracket`, `handle`, and `finally` now work on streams that aren't
23− fully drained.
23+ fully drained. Also, the resource acquisition and release is atomic with
24+ respect to async exceptions.
24
25
25## 0.7.2
26## 0.7.2
26
27
src/Streamly/Internal/Data/Stream/StreamD.hs+6−2
@@ -3217,8 +3217,12 @@ runIORefFinalizer ref = liftIO $ do
3217 case res of
3217 case res of
3218 Nothing -> return ()
3218 Nothing -> return ()
3219 Just action -> do
3219 Just action -> do
3220+ -- if an async exception comes after writing 'Nothing' then the
3221+ -- finalizing action will never be run. We need to do this
3222+ -- atomically wrt async exceptions.
3223+ mask_ $ do
3220− writeIORef ref Nothing
3224+ writeIORef ref Nothing
3221− action
3225+ action
3222
3226
3223-- | Deactivate the finalizer stored in an IORef without running it.
3227-- | Deactivate the finalizer stored in an IORef without running it.
3224--
3228--