{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Concurrent.Classy.RWLock
(
RWLock
, newRWLock
, newAcquiredRead
, newAcquiredWrite
, acquireRead
, releaseRead
, withRead
, waitRead
, tryAcquireRead
, tryWithRead
, acquireWrite
, releaseWrite
, withWrite
, waitWrite
, tryAcquireWrite
, tryWithWrite
) where
import Control.Applicative (pure, (<*>))
import Control.Monad (Monad, (>>))
import Data.Bool (Bool(False, True))
import Data.Eq (Eq, (==))
import Data.Function (on, ($))
import Data.Functor ((<$>))
import Data.Int (Int)
import Data.List ((++))
import Data.Maybe (Maybe(Just, Nothing))
import Data.Ord (Ord)
import Data.Typeable (Typeable)
import Prelude (String, error, pred, succ)
import Text.Read (Read)
import Text.Show (Show)
import qualified Control.Concurrent.Classy.MVar as MVar
import Control.Monad.Catch (bracket_, mask, mask_,
onException)
import Control.Monad.Conc.Class (MonadConc(MVar))
import Control.Concurrent.Classy.Lock (Lock)
import qualified Control.Concurrent.Classy.Lock as Lock
data RWLock m
= RWLock
{ forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
, forall (m :: * -> *). RWLock m -> Lock m
_readLock :: Lock m
, forall (m :: * -> *). RWLock m -> Lock m
_writeLock :: Lock m
}
deriving (Typeable)
instance (Eq (MVar m State)) => Eq (RWLock m) where
== :: RWLock m -> RWLock m -> Bool
(==) = MVar m State -> MVar m State -> Bool
forall a. Eq a => a -> a -> Bool
(==) (MVar m State -> MVar m State -> Bool)
-> (RWLock m -> MVar m State) -> RWLock m -> RWLock m -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` RWLock m -> MVar m State
forall (m :: * -> *). RWLock m -> MVar m State
_state
data State
= Free
| Read !Int
| Write
deriving (State -> State -> Bool
(State -> State -> Bool) -> (State -> State -> Bool) -> Eq State
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: State -> State -> Bool
== :: State -> State -> Bool
$c/= :: State -> State -> Bool
/= :: State -> State -> Bool
Eq, Eq State
Eq State =>
(State -> State -> Ordering)
-> (State -> State -> Bool)
-> (State -> State -> Bool)
-> (State -> State -> Bool)
-> (State -> State -> Bool)
-> (State -> State -> State)
-> (State -> State -> State)
-> Ord State
State -> State -> Bool
State -> State -> Ordering
State -> State -> State
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: State -> State -> Ordering
compare :: State -> State -> Ordering
$c< :: State -> State -> Bool
< :: State -> State -> Bool
$c<= :: State -> State -> Bool
<= :: State -> State -> Bool
$c> :: State -> State -> Bool
> :: State -> State -> Bool
$c>= :: State -> State -> Bool
>= :: State -> State -> Bool
$cmax :: State -> State -> State
max :: State -> State -> State
$cmin :: State -> State -> State
min :: State -> State -> State
Ord, Int -> State -> ShowS
[State] -> ShowS
State -> String
(Int -> State -> ShowS)
-> (State -> String) -> ([State] -> ShowS) -> Show State
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> State -> ShowS
showsPrec :: Int -> State -> ShowS
$cshow :: State -> String
show :: State -> String
$cshowList :: [State] -> ShowS
showList :: [State] -> ShowS
Show, ReadPrec [State]
ReadPrec State
Int -> ReadS State
ReadS [State]
(Int -> ReadS State)
-> ReadS [State]
-> ReadPrec State
-> ReadPrec [State]
-> Read State
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS State
readsPrec :: Int -> ReadS State
$creadList :: ReadS [State]
readList :: ReadS [State]
$creadPrec :: ReadPrec State
readPrec :: ReadPrec State
$creadListPrec :: ReadPrec [State]
readListPrec :: ReadPrec [State]
Read)
newRWLock :: (MonadConc m) => m (RWLock m)
newRWLock :: forall (m :: * -> *). MonadConc m => m (RWLock m)
newRWLock = do
MVar m State
state <- State -> m (MVar m State)
forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
MVar.newMVar State
Free
Lock m
rlock <- m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newLock
MVar m State -> Lock m -> Lock m -> RWLock m
forall (m :: * -> *). MVar m State -> Lock m -> Lock m -> RWLock m
RWLock MVar m State
state Lock m
rlock (Lock m -> RWLock m) -> m (Lock m) -> m (RWLock m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newLock
newAcquiredRead :: (MonadConc m) => m (RWLock m)
newAcquiredRead :: forall (m :: * -> *). MonadConc m => m (RWLock m)
newAcquiredRead = do
MVar m State
state <- State -> m (MVar m State)
forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
MVar.newMVar (Int -> State
Read Int
1)
Lock m
rlock <- m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newAcquired
MVar m State -> Lock m -> Lock m -> RWLock m
forall (m :: * -> *). MVar m State -> Lock m -> Lock m -> RWLock m
RWLock MVar m State
state Lock m
rlock (Lock m -> RWLock m) -> m (Lock m) -> m (RWLock m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newLock
newAcquiredWrite :: (MonadConc m) => m (RWLock m)
newAcquiredWrite :: forall (m :: * -> *). MonadConc m => m (RWLock m)
newAcquiredWrite = do
MVar m State
state <- State -> m (MVar m State)
forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
MVar.newMVar State
Write
Lock m
rlock <- m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newLock
MVar m State -> Lock m -> Lock m -> RWLock m
forall (m :: * -> *). MVar m State -> Lock m -> Lock m -> RWLock m
RWLock MVar m State
state Lock m
rlock (Lock m -> RWLock m) -> m (Lock m) -> m (RWLock m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Lock m)
forall (m :: * -> *). MonadConc m => m (Lock m)
Lock.newAcquired
acquireRead :: (MonadConc m) => RWLock m -> m ()
acquireRead :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireRead RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_readLock :: forall (m :: * -> *). RWLock m -> Lock m
_readLock :: Lock m
_readLock, Lock m
_writeLock :: forall (m :: * -> *). RWLock m -> Lock m
_writeLock :: Lock m
_writeLock } = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ m ()
go
where
go :: m ()
go = do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
State
Free -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.acquire Lock m
_readLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state (State -> m ()) -> State -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> State
Read Int
1
(Read Int
n) -> MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state (State -> m ()) -> State -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> State
Read (Int -> Int
forall a. Enum a => a -> a
succ Int
n)
State
Write -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.wait Lock m
_writeLock
m ()
go
tryAcquireRead :: (MonadConc m) => RWLock m -> m Bool
tryAcquireRead :: forall (m :: * -> *). MonadConc m => RWLock m -> m Bool
tryAcquireRead RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_readLock :: forall (m :: * -> *). RWLock m -> Lock m
_readLock :: Lock m
_readLock } = m Bool -> m Bool
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (m Bool -> m Bool) -> m Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
State
Free -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.acquire Lock m
_readLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state (State -> m ()) -> State -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> State
Read Int
1
Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
Read Int
n -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state (State -> m ()) -> State -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> State
Read (Int -> Int
forall a. Enum a => a -> a
succ Int
n)
Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
State
Write -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
releaseRead :: (MonadConc m) => RWLock m -> m ()
releaseRead :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseRead RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_readLock :: forall (m :: * -> *). RWLock m -> Lock m
_readLock :: Lock m
_readLock } = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
Read Int
1 -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.release Lock m
_readLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
Free
Read Int
n -> MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state (State -> m ()) -> State -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> State
Read (Int -> Int
forall a. Enum a => a -> a
pred Int
n)
State
_ -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
String -> String -> m ()
forall (m :: * -> *) a. Monad m => String -> String -> m a
throw String
"releaseRead" String
"already released"
withRead :: (MonadConc m) => RWLock m -> m a -> m a
withRead :: forall (m :: * -> *) a. MonadConc m => RWLock m -> m a -> m a
withRead = m () -> m () -> m a -> m a
forall (m :: * -> *) a c b.
(HasCallStack, MonadMask m) =>
m a -> m c -> m b -> m b
bracket_ (m () -> m () -> m a -> m a)
-> (RWLock m -> m ()) -> RWLock m -> m () -> m a -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireRead (RWLock m -> m () -> m a -> m a)
-> (RWLock m -> m ()) -> RWLock m -> m a -> m a
forall a b.
(RWLock m -> a -> b) -> (RWLock m -> a) -> RWLock m -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseRead
tryWithRead :: (MonadConc m) => RWLock m -> m a -> m (Maybe a)
tryWithRead :: forall (m :: * -> *) a.
MonadConc m =>
RWLock m -> m a -> m (Maybe a)
tryWithRead RWLock m
l m a
a = ((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a)
forall b. HasCallStack => ((forall a. m a -> m a) -> m b) -> m b
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a))
-> ((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
Bool
acquired <- RWLock m -> m Bool
forall (m :: * -> *). MonadConc m => RWLock m -> m Bool
tryAcquireRead RWLock m
l
if Bool
acquired
then do a
r <- m a -> m a
forall a. m a -> m a
restore m a
a m a -> m () -> m a
forall (m :: * -> *) a b.
(HasCallStack, MonadCatch m) =>
m a -> m b -> m a
`onException` RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseRead RWLock m
l
RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseRead RWLock m
l
Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just a
r
else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
waitRead :: (MonadConc m) => RWLock m -> m ()
waitRead :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
waitRead RWLock m
l = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireRead RWLock m
l m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseRead RWLock m
l)
acquireWrite :: (MonadConc m) => RWLock m -> m ()
acquireWrite :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireWrite RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_readLock :: forall (m :: * -> *). RWLock m -> Lock m
_readLock :: Lock m
_readLock, Lock m
_writeLock :: forall (m :: * -> *). RWLock m -> Lock m
_writeLock :: Lock m
_writeLock } = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ m ()
go'
where
go' :: m ()
go' = do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
State
Free -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.acquire Lock m
_writeLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
Write
Read Int
_ -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.wait Lock m
_readLock
m ()
go'
State
Write -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.wait Lock m
_writeLock
m ()
go'
tryAcquireWrite :: (MonadConc m) => RWLock m -> m Bool
tryAcquireWrite :: forall (m :: * -> *). MonadConc m => RWLock m -> m Bool
tryAcquireWrite RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_writeLock :: forall (m :: * -> *). RWLock m -> Lock m
_writeLock :: Lock m
_writeLock } = m Bool -> m Bool
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (m Bool -> m Bool) -> m Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
State
Free -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.acquire Lock m
_writeLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
Write
Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
State
_ -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
releaseWrite :: (MonadConc m) => RWLock m -> m ()
releaseWrite :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseWrite RWLock { MVar m State
_state :: forall (m :: * -> *). RWLock m -> MVar m State
_state :: MVar m State
_state, Lock m
_writeLock :: forall (m :: * -> *). RWLock m -> Lock m
_writeLock :: Lock m
_writeLock } = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
State
st <- MVar m State -> m State
forall a. MVar m a -> m a
forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
MVar.takeMVar MVar m State
_state
case State
st of
State
Write -> do Lock m -> m ()
forall (m :: * -> *). MonadConc m => Lock m -> m ()
Lock.release Lock m
_writeLock
MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
Free
State
_ -> do MVar m State -> State -> m ()
forall a. MVar m a -> a -> m ()
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
MVar.putMVar MVar m State
_state State
st
String -> String -> m ()
forall (m :: * -> *) a. Monad m => String -> String -> m a
throw String
"releaseWrite" String
"already released"
withWrite :: (MonadConc m) => RWLock m -> m a -> m a
withWrite :: forall (m :: * -> *) a. MonadConc m => RWLock m -> m a -> m a
withWrite = m () -> m () -> m a -> m a
forall (m :: * -> *) a c b.
(HasCallStack, MonadMask m) =>
m a -> m c -> m b -> m b
bracket_ (m () -> m () -> m a -> m a)
-> (RWLock m -> m ()) -> RWLock m -> m () -> m a -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireWrite (RWLock m -> m () -> m a -> m a)
-> (RWLock m -> m ()) -> RWLock m -> m a -> m a
forall a b.
(RWLock m -> a -> b) -> (RWLock m -> a) -> RWLock m -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseWrite
tryWithWrite :: (MonadConc m) => RWLock m -> m a -> m (Maybe a)
tryWithWrite :: forall (m :: * -> *) a.
MonadConc m =>
RWLock m -> m a -> m (Maybe a)
tryWithWrite RWLock m
l m a
a = ((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a)
forall b. HasCallStack => ((forall a. m a -> m a) -> m b) -> m b
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a))
-> ((forall a. m a -> m a) -> m (Maybe a)) -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
Bool
acquired <- RWLock m -> m Bool
forall (m :: * -> *). MonadConc m => RWLock m -> m Bool
tryAcquireWrite RWLock m
l
if Bool
acquired
then do a
r <- m a -> m a
forall a. m a -> m a
restore m a
a m a -> m () -> m a
forall (m :: * -> *) a b.
(HasCallStack, MonadCatch m) =>
m a -> m b -> m a
`onException` RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseWrite RWLock m
l
RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseWrite RWLock m
l
Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just a
r
else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
waitWrite :: (MonadConc m) => RWLock m -> m ()
waitWrite :: forall (m :: * -> *). MonadConc m => RWLock m -> m ()
waitWrite RWLock m
l = m () -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadMask m) => m a -> m a
mask_ (RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
acquireWrite RWLock m
l m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RWLock m -> m ()
forall (m :: * -> *). MonadConc m => RWLock m -> m ()
releaseWrite RWLock m
l)
throw :: (Monad m) => String -> String -> m a
throw :: forall (m :: * -> *) a. Monad m => String -> String -> m a
throw String
func String
msg
= String -> m a
forall a. HasCallStack => String -> a
error (String
"Control.Concurrent.Classy.RWLock." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
func String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg)