module Development.Shake.Locks( Lock, newLock, withLock, Var, newVar, readVar, modifyVar, modifyVar_, Barrier, newBarrier, signalBarrier, waitBarrier, ) where import Control.Concurrent --------------------------------------------------------------------- -- LOCK -- | Like an MVar, but has no value newtype Lock = Lock (MVar ()) instance Show Lock where show _ = "Lock" newLock :: IO Lock newLock = fmap Lock $ newMVar () withLock :: Lock -> IO a -> IO a withLock (Lock x) = withMVar x . const --------------------------------------------------------------------- -- VAR -- | Like an MVar, but must always be full newtype Var a = Var (MVar a) instance Show (Var a) where show _ = "Var" newVar :: a -> IO (Var a) newVar = fmap Var . newMVar readVar :: Var a -> IO a readVar (Var x) = readMVar x modifyVar :: Var a -> (a -> IO (a, b)) -> IO b modifyVar (Var x) f = modifyMVar x f modifyVar_ :: Var a -> (a -> IO a) -> IO () modifyVar_ (Var x) f = modifyMVar_ x f --------------------------------------------------------------------- -- BARRIER -- | Starts out empty, then is filled exactly once newtype Barrier a = Barrier (MVar a) instance Show (Barrier a) where show _ = "Barrier" newBarrier :: IO (Barrier a) newBarrier = fmap Barrier newEmptyMVar signalBarrier :: Barrier a -> a -> IO () signalBarrier (Barrier x) = putMVar x waitBarrier :: Barrier a -> IO a waitBarrier (Barrier x) = readMVar x