X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Futils%2FIOEnv.hs;h=1f1dd8fec40b361a7e4e4db5a6bd3f48299b7804;hp=5f354f0e4d96ee84d14bce08271b1b3cc4d8008c;hb=c5b178be60a5a44abd2f4ddf8c399857678326e2;hpb=2b670a7983da26c0f186d5ebdf195e47a39ee60e diff --git a/compiler/utils/IOEnv.hs b/compiler/utils/IOEnv.hs index 5f354f0..1f1dd8f 100644 --- a/compiler/utils/IOEnv.hs +++ b/compiler/utils/IOEnv.hs @@ -22,13 +22,15 @@ module IOEnv ( tryM, tryAllM, tryMostM, fixM, -- I/O operations - IORef, newMutVar, readMutVar, writeMutVar, updMutVar + IORef, newMutVar, readMutVar, writeMutVar, updMutVar, + atomicUpdMutVar, atomicUpdMutVar' ) where import Exception import Panic -import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef ) +import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef, + atomicModifyIORef ) import Data.Typeable import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO ( fixIO ) @@ -66,7 +68,7 @@ thenM (IOEnv m) f = IOEnv (\ env -> do { r <- m env ; unIOEnv (f r) env }) thenM_ :: IOEnv env a -> IOEnv env b -> IOEnv env b -thenM_ (IOEnv m) f = IOEnv (\ env -> do { m env ; unIOEnv f env }) +thenM_ (IOEnv m) f = IOEnv (\ env -> do { _ <- m env ; unIOEnv f env }) failM :: IOEnv env a failM = IOEnv (\ _ -> throwIO IOEnvFailure) @@ -139,15 +141,9 @@ unsafeInterleaveM (IOEnv m) = IOEnv (\ env -> unsafeInterleaveIO (m env)) -- For use if the user has imported Control.Monad.Error from MTL -- Requires UndecidableInstances -#if __GLASGOW_HASKELL__ > 606 --- for some reason, this doesn't compile with GHC 6.6: --- utils/IOEnv.hs:144:33: --- No instance for (MonadPlus IO) --- arising from use of `mplus' at utils/IOEnv.hs:144:33-67 instance MonadPlus IO => MonadPlus (IOEnv env) where mzero = IOEnv (const mzero) m `mplus` n = IOEnv (\env -> unIOEnv m env `mplus` unIOEnv n env) -#endif ---------------------------------------------------------------------- -- Accessing input/output @@ -168,6 +164,17 @@ readMutVar var = liftIO (readIORef var) updMutVar :: IORef a -> (a -> a) -> IOEnv env () updMutVar var upd = liftIO (modifyIORef var upd) +-- | Atomically update the reference. Does not force the evaluation of the +-- new variable contents. For strict update, use 'atomicUpdMutVar''. +atomicUpdMutVar :: IORef a -> (a -> (a, b)) -> IOEnv env b +atomicUpdMutVar var upd = liftIO (atomicModifyIORef var upd) + +-- | Strict variant of 'atomicUpdMutVar'. +atomicUpdMutVar' :: IORef a -> (a -> (a, b)) -> IOEnv env b +atomicUpdMutVar' var upd = do + r <- atomicUpdMutVar var upd + _ <- liftIO . evaluate =<< readMutVar var + return r ---------------------------------------------------------------------- -- Accessing the environment