module Simulation.Aivika.Experiment.Concurrent.MVar
(maybeReadMVar,
maybePutMVar) where
import Control.Exception
import Control.Concurrent.MVar
import Data.Maybe
maybeReadMVar :: b -> (a -> IO b) -> MVar (Maybe a) -> IO b
maybeReadMVar :: forall b a. b -> (a -> IO b) -> MVar (Maybe a) -> IO b
maybeReadMVar b
b0 a -> IO b
f MVar (Maybe a)
x =
do Maybe a
a <- MVar (Maybe a) -> IO (Maybe a)
forall a. MVar a -> IO a
readMVar MVar (Maybe a)
x
case Maybe a
a of
Just a
a -> a -> IO b
f a
a
Maybe a
Nothing -> b -> IO b
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return b
b0
maybePutMVar :: MVar (Maybe a) -> IO a -> (a -> IO b) -> IO b
maybePutMVar :: forall a b. MVar (Maybe a) -> IO a -> (a -> IO b) -> IO b
maybePutMVar MVar (Maybe a)
x IO a
m0 a -> IO b
f =
IO b -> IO b
forall a. IO a -> IO a
mask_ (IO b -> IO b) -> IO b -> IO b
forall a b. (a -> b) -> a -> b
$
do Maybe a
a <- MVar (Maybe a) -> IO (Maybe a)
forall a. MVar a -> IO a
takeMVar MVar (Maybe a)
x
case Maybe a
a of
Just a
a ->
do MVar (Maybe a) -> Maybe a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Maybe a)
x (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
a -> IO b
f a
a
Maybe a
Nothing ->
do let handle :: SomeException -> IO a
handle :: forall a. SomeException -> IO a
handle SomeException
e = do MVar (Maybe a) -> Maybe a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Maybe a)
x Maybe a
forall a. Maybe a
Nothing
SomeException -> IO a
forall a e. Exception e => e -> a
throw SomeException
e
a
a0 <- IO a -> (SomeException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch IO a
m0 SomeException -> IO a
forall a. SomeException -> IO a
handle
MVar (Maybe a) -> Maybe a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Maybe a)
x (a -> Maybe a
forall a. a -> Maybe a
Just a
a0)
a -> IO b
f a
a0