module Control.Concurrent.MVarLock
( Lock, newLock, acquireLock, releaseLock, withLock
) where
import Control.Concurrent.MVar (MVar, newMVar, putMVar, takeMVar)
import Control.Exception.Safe (finally)
import Prelude ((<$>), (*>), IO)
newtype Lock = Lock (MVar ())
newLock :: IO Lock
newLock :: IO Lock
newLock = MVar () -> Lock
Lock (MVar () -> Lock) -> IO (MVar ()) -> IO Lock
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> () -> IO (MVar ())
forall a. a -> IO (MVar a)
newMVar ()
acquireLock :: Lock -> IO ()
acquireLock :: Lock -> IO ()
acquireLock (Lock MVar ()
v) = MVar () -> IO ()
forall a. MVar a -> IO a
takeMVar MVar ()
v
releaseLock :: Lock -> IO ()
releaseLock :: Lock -> IO ()
releaseLock (Lock MVar ()
v) = MVar () -> () -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar ()
v ()
withLock :: Lock -> IO a -> IO a
withLock :: Lock -> IO a -> IO a
withLock Lock
lock IO a
action =
(Lock -> IO ()
acquireLock Lock
lock IO () -> IO a -> IO a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> IO a
action) IO a -> IO () -> IO a
forall (m :: * -> *) a b. MonadMask m => m a -> m b -> m a
`finally` (Lock -> IO ()
releaseLock Lock
lock)