on master help sign in
Fix atomicity issue when running a finalizer

The clearing of finalizer from GC hook and running the finalizing action must be atomic wrt async exceptions.

commita54a1ae9d2724d0cc35f0739370dd5c60e07962d authorHarendra Kumar <harendra@composewell.com> dateSat 22 Aug 2020, 09:52 (6 years ago) parentbd7c518
2 files changed+8−3
Changelog.md+2−1 src/Streamly/Internal/Data/Stream/StreamD.hs+6−2
Changelog.md+2−1
@@ -20,7 +20,8 @@
2020 API in `Streamly.Network.Socket` now close the socket if an exception is
2121 thrown.
2222* `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.
2425
2526## 0.7.2
2627
src/Streamly/Internal/Data/Stream/StreamD.hs+6−2
@@ -3217,8 +3217,12 @@ runIORefFinalizer ref = liftIO $ do
32173217 case res of
32183218 Nothing -> return ()
32193219 Just action -> do
3220− writeIORef ref Nothing
3221− action
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
3224+ writeIORef ref Nothing
3225+ action
32223226
32233227-- | Deactivate the finalizer stored in an IORef without running it.
32243228--