aivika-experiment-5.0: Simulation/Aivika/Experiment/Concurrent/MVar.hs
-- |
-- Module : Simulation.Aivika.Experiment.Concurrent.MVar
-- Copyright : Copyright (c) 2012-2017, David Sorokin <david.sorokin@gmail.com>
-- License : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability : experimental
-- Tested with: GHC 8.0.1
--
-- The module defines helper functions for working with synchronized variable 'MVar'.
--
module Simulation.Aivika.Experiment.Concurrent.MVar
(maybeReadMVar,
maybePutMVar) where
import Control.Exception
import Control.Concurrent.MVar
import Data.Maybe
-- | Like 'maybe' but for the synchronized variable.
maybeReadMVar :: b -> (a -> IO b) -> MVar (Maybe a) -> IO b
maybeReadMVar b0 f x =
do a <- readMVar x
case a of
Just a -> f a
Nothing -> return b0
-- | Update the contents if the variable was empty and then return a result of
-- applying the specified function to either the initial or current value.
maybePutMVar :: MVar (Maybe a) -> IO a -> (a -> IO b) -> IO b
maybePutMVar x m0 f =
mask_ $
do a <- takeMVar x
case a of
Just a ->
do putMVar x (Just a)
f a
Nothing ->
do let handle :: SomeException -> IO a
handle e = do putMVar x Nothing
throw e
a0 <- catch m0 handle
putMVar x (Just a0)
f a0