Skip to content

Commit

Permalink
force new value of StrictMVar before calling putTMVar in updateMVar
Browse files Browse the repository at this point in the history
yes, this is an odd-looking change. it's not unreasonable to assume that forcing !(!a', b) inside the atomically block will force the new value before putting it into the MVar, but there's actually an additional closure constructed (with a dependency on a') that will only force a' when *it's* evaluated! in order to ensure that we're forcing the value inside the MVar before calling checkInvariant, we need an additional bang outside the atomically block, which will correctly force a' before checkInvariant looks to see if it's been evaluated or not. without this change, it's possible to put a lazy value inside a StrictMVar (though it's very unlikely that this has happened in the past in production environments because this intermediate unforced closure is optimized away at -O1 and above)
  • Loading branch information
fraser-iohk committed May 31, 2023
1 parent fb5754f commit f8e5343
Showing 1 changed file with 1 addition and 1 deletion.
Expand Up @@ -168,7 +168,7 @@ isEmptyMVar StrictMVar { tmvar } = atomically $ Lazy.isEmptyTMVar tmvar

updateMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> (a -> (a, b)) -> m b
updateMVar StrictMVar { tmvar, tvar, invariant } f = do
(a', b) <- atomically $ do
(!a', b) <- atomically $ do
a <- Lazy.takeTMVar tmvar
let !(!a', b) = f a
Lazy.putTMVar tmvar a'
Expand Down

0 comments on commit f8e5343

Please sign in to comment.