modifyMVarMasked :: StrictMVar a -> (a -> IO (a, b)) -> IO b
modifyMVarMasked (StrictMVar v) f =
#if MIN_VERSION_base(4,6,0)
    MVar.modifyMVarMasked v (f >=> evaluateFst)
#else
  mask_ $ do
    a      <- MVar.takeMVar v
    (a',b) <- (f a >>= evaluate) `onException` MVar.putMVar v a
    MVar.putMVar v a'
    return b
#endif
  where
    evaluateFst :: (a, b) -> IO (a, b)
    evaluateFst (x, y) = evaluate x >> return (x, y)
modifyMVarMasked :: StrictMVar a -> (a -> IO (a, b)) -> IO b
modifyMVarMasked (StrictMVar v) f =
#if MIN_VERSION_base(4,6,0)
    MVar.modifyMVarMasked v (f >=> evaluateFst)
#else
  mask_ $ do
    a      <- MVar.takeMVar v
    (a',b) <- (f a >>= evaluate) `onException` MVar.putMVar v a
    MVar.putMVar v a'
    return b
#endif
  where
    evaluateFst :: (a, b) -> IO (a, b)
    evaluateFst (x, y) = evaluate x >> return (x, y)
modifyMVarMasked (StrictMVar v) f =
#if MIN_VERSION_base(4,6,0)
    MVar.modifyMVarMasked v (f >=> evaluateFst)
#else
  mask_ $ do
    a      <- MVar.takeMVar v
    (a',b) <- (f a >>= evaluate) `onException` MVar.putMVar v a
    MVar.putMVar v a'
    return b
#endif
  where
    evaluateFst :: (a, b) -> IO (a, b)
    evaluateFst (x, y) = evaluate x >> return (x, y)