module Simulation.Aivika.Experiment.MRef
(MRef,
newMRef,
readMRef,
maybeReadMRef,
writeMRef,
maybeWriteMRef,
modifyMRef_,
modifyMRef,
withMRef) where
import Control.Concurrent.MVar
import Data.Maybe
import Data.IORef
data MRef a =
MRef { mrefLock :: MVar (),
mrefData :: IORef a
}
newMRef :: a -> IO (MRef a)
newMRef a =
do v <- newMVar ()
r <- newIORef a
return MRef { mrefLock = v,
mrefData = r }
readMRef :: MRef a -> IO a
readMRef = readIORef . mrefData
maybeReadMRef :: b -> (a -> IO b) -> MRef (Maybe a) -> IO b
maybeReadMRef b0 f x =
do a <- readIORef (mrefData x)
case a of
Just a -> f a
Nothing ->
withMVar (mrefLock x) $ \() ->
do a <- readIORef (mrefData x)
case a of
Just a -> f a
Nothing -> return b0
writeMRef :: MRef a -> a -> IO ()
writeMRef x a =
withMVar (mrefLock x) $ \() ->
writeIORef (mrefData x) a
maybeWriteMRef :: MRef (Maybe a) -> IO a -> (a -> IO b) -> IO b
maybeWriteMRef x m0 f =
do a <- readIORef (mrefData x)
case a of
Just a -> f a
Nothing ->
withMVar (mrefLock x) $ \() ->
do a <- readIORef (mrefData x)
case a of
Just a -> f a
Nothing ->
do a0 <- m0
writeIORef (mrefData x) (Just a0)
f a0
modifyMRef_ :: MRef a -> (a -> IO a) -> IO ()
modifyMRef_ x f =
withMVar (mrefLock x) $ \() ->
do a <- readIORef (mrefData x)
a' <- f a
writeIORef (mrefData x) a'
modifyMRef :: MRef a -> (a -> IO (a, b)) -> IO b
modifyMRef x f =
withMVar (mrefLock x) $ \() ->
do a <- readIORef (mrefData x)
(a', b) <- f a
writeIORef (mrefData x) a'
return b
withMRef :: MRef a -> (a -> IO b) -> IO b
withMRef x f =
withMVar (mrefLock x) $ \() ->
readIORef (mrefData x) >>= f