-- | A trivial mutex. module Data.Mutex where import Prelude import Data.Var data Mutex = Mutex (Var Bool) -- | Make a new unlocked mutex. newMutex :: Fay Mutex newMutex = do v <- newVar False return (Mutex v) -- | If a mutex is free run the action, otherwise don't. ifMutexFree :: Mutex -> Fay () -> Fay () ifMutexFree (Mutex var) action = do locked <- get var if locked then return () else action -- | Wait until the mutex is free to do something. whenMutexFree :: Mutex -> Fay () -> Fay () whenMutexFree (Mutex var) cont = do locked <- get var if locked then do _ <- withUnsubscriber (subscribe var) (\unsubscribe lockedNow -> if lockedNow then return () else do unsubscribe () cont) return () else cont -- | Lock the given mutex until I'm done with it. lockMutex :: Mutex -> (Fay () -> Fay a) -> Fay a lockMutex (Mutex var) cont = do locked <- get var if locked then error "mutex is already locked" else do set var True cont (set var False)