{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Consensus.Util.MonadSTM.RAWLock (
RAWLock
, new
, poison
, read
, withAppendAccess
, withReadAccess
, withWriteAccess
, unsafeAcquireAppendAccess
, unsafeAcquireReadAccess
, unsafeAcquireWriteAccess
, unsafeReleaseAppendAccess
, unsafeReleaseReadAccess
, unsafeReleaseWriteAccess
) where
import Prelude hiding (read)
import Control.Monad.Except
import Data.Functor (($>))
import GHC.Generics (Generic)
import GHC.Stack (CallStack, HasCallStack, callStack)
import NoThunks.Class (AllowThunk (..))
import Ouroboros.Consensus.Util.IOLike
newtype RAWLock m st = RAWLock (StrictTVar m (RAWState st))
new :: (IOLike m, NoThunks st) => st -> m (RAWLock m st)
new :: st -> m (RAWLock m st)
new st
st = StrictTVar m (RAWState st) -> RAWLock m st
forall (m :: * -> *) st. StrictTVar m (RAWState st) -> RAWLock m st
RAWLock (StrictTVar m (RAWState st) -> RAWLock m st)
-> m (StrictTVar m (RAWState st)) -> m (RAWLock m st)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RAWState st -> m (StrictTVar m (RAWState st))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO (st -> RAWState st
forall st. st -> RAWState st
emptyRAWState st
st)
withReadAccess :: forall m st a. IOLike m => RAWLock m st -> (st -> m a) -> m a
withReadAccess :: RAWLock m st -> (st -> m a) -> m a
withReadAccess RAWLock m st
rawLock =
m st -> (st -> m ()) -> (st -> m a) -> m a
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket
(STM m st -> m st
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m st -> m st) -> STM m st -> m st
forall a b. (a -> b) -> a -> b
$ RAWLock m st -> STM m st
forall (m :: * -> *) st. IOLike m => RAWLock m st -> STM m st
unsafeAcquireReadAccess RAWLock m st
rawLock)
(m () -> st -> m ()
forall a b. a -> b -> a
const (STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ RAWLock m st -> STM m ()
forall (m :: * -> *) st. IOLike m => RAWLock m st -> STM m ()
unsafeReleaseReadAccess RAWLock m st
rawLock))
withAppendAccess
:: forall m st a. IOLike m => RAWLock m st -> (st -> m (st, a)) -> m a
withAppendAccess :: RAWLock m st -> (st -> m (st, a)) -> m a
withAppendAccess RAWLock m st
rawLock st -> m (st, a)
k = (st, a) -> a
forall a b. (a, b) -> b
snd ((st, a) -> a) -> (((st, a), ()) -> (st, a)) -> ((st, a), ()) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((st, a), ()) -> (st, a)
forall a b. (a, b) -> a
fst (((st, a), ()) -> a) -> m ((st, a), ()) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
m st
-> (st -> ExitCase (st, a) -> m ())
-> (st -> m (st, a))
-> m ((st, a), ())
forall (m :: * -> *) a b c.
MonadCatch m =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
generalBracket
(STM m st -> m st
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m st -> m st) -> STM m st -> m st
forall a b. (a -> b) -> a -> b
$ RAWLock m st -> STM m st
forall (m :: * -> *) st. IOLike m => RAWLock m st -> STM m st
unsafeAcquireAppendAccess RAWLock m st
rawLock)
(\st
acquiredSt ExitCase (st, a)
exitCase ->
STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ RAWLock m st -> st -> STM m ()
forall (m :: * -> *) st. IOLike m => RAWLock m st -> st -> STM m ()
unsafeReleaseAppendAccess
RAWLock m st
rawLock
(st -> ExitCase (st, a) -> st
forall st a. st -> ExitCase (st, a) -> st
stateToPutBack st
acquiredSt ExitCase (st, a)
exitCase))
st -> m (st, a)
k
withWriteAccess
:: forall m st a. IOLike m => RAWLock m st -> (st -> m (st, a)) -> m a
withWriteAccess :: RAWLock m st -> (st -> m (st, a)) -> m a
withWriteAccess RAWLock m st
rawLock st -> m (st, a)
k = (st, a) -> a
forall a b. (a, b) -> b
snd ((st, a) -> a) -> (((st, a), ()) -> (st, a)) -> ((st, a), ()) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((st, a), ()) -> (st, a)
forall a b. (a, b) -> a
fst (((st, a), ()) -> a) -> m ((st, a), ()) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
m st
-> (st -> ExitCase (st, a) -> m ())
-> (st -> m (st, a))
-> m ((st, a), ())
forall (m :: * -> *) a b c.
MonadCatch m =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
generalBracket
(RAWLock m st -> m st
forall (m :: * -> *) st. IOLike m => RAWLock m st -> m st
unsafeAcquireWriteAccess RAWLock m st
rawLock)
(\st
acquiredSt ExitCase (st, a)
exitCase ->
RAWLock m st -> st -> m ()
forall (m :: * -> *) st. IOLike m => RAWLock m st -> st -> m ()
unsafeReleaseWriteAccess
RAWLock m st
rawLock
(st -> ExitCase (st, a) -> st
forall st a. st -> ExitCase (st, a) -> st
stateToPutBack st
acquiredSt ExitCase (st, a)
exitCase))
st -> m (st, a)
k
stateToPutBack
:: st
-> ExitCase (st, a)
-> st
stateToPutBack :: st -> ExitCase (st, a) -> st
stateToPutBack st
acquiredSt = \case
ExitCaseSuccess (st
modifiedSt, a
_a) -> st
modifiedSt
ExitCaseException SomeException
_ex -> st
acquiredSt
ExitCase (st, a)
ExitCaseAbort -> st
acquiredSt
read :: IOLike m => RAWLock m st -> STM m st
read :: RAWLock m st -> STM m st
read (RAWLock StrictTVar m (RAWState st)
var) = StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var STM m (RAWState st) -> (RAWState st -> STM m st) -> STM m st
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
ReadAppend Readers
_readers Appender
_appender st
st -> st -> STM m st
forall (m :: * -> *) a. Monad m => a -> m a
return st
st
WaitingToWrite Readers
_readers Appender
_appender st
st -> st -> STM m st
forall (m :: * -> *) a. Monad m => a -> m a
return st
st
RAWState st
Writing -> STM m st
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
Poisoned (AllowThunk SomeException
ex) -> SomeException -> STM m st
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM SomeException
ex
poison
:: (IOLike m, Exception e, HasCallStack)
=> RAWLock m st -> (CallStack -> e) -> m (Maybe st)
poison :: RAWLock m st -> (CallStack -> e) -> m (Maybe st)
poison (RAWLock StrictTVar m (RAWState st)
var) CallStack -> e
mkEx = STM m (Maybe st) -> m (Maybe st)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (Maybe st) -> m (Maybe st))
-> STM m (Maybe st) -> m (Maybe st)
forall a b. (a -> b) -> a -> b
$ do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
(RAWState st
rawSt', Maybe st
mbSt) <-
Except SomeException (RAWState st, Maybe st)
-> STM m (RAWState st, Maybe st)
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (SomeException
-> RAWState st -> Except SomeException (RAWState st, Maybe st)
forall st.
SomeException
-> RAWState st -> Except SomeException (RAWState st, Maybe st)
poisonPure (e -> SomeException
forall e. Exception e => e -> SomeException
toException (CallStack -> e
mkEx CallStack
HasCallStack => CallStack
callStack)) RAWState st
rawSt)
StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var RAWState st
rawSt'
Maybe st -> STM m (Maybe st)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe st
mbSt
withPoisoned :: MonadThrow m => Except SomeException a -> m a
withPoisoned :: Except SomeException a -> m a
withPoisoned = (SomeException -> m a)
-> (a -> m a) -> Either SomeException a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SomeException -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SomeException a -> m a)
-> (Except SomeException a -> Either SomeException a)
-> Except SomeException a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Except SomeException a -> Either SomeException a
forall e a. Except e a -> Either e a
runExcept
unsafeAcquireReadAccess :: IOLike m => RAWLock m st -> STM m st
unsafeAcquireReadAccess :: RAWLock m st -> STM m st
unsafeAcquireReadAccess (RAWLock StrictTVar m (RAWState st)
var) = do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (Maybe (RAWState st, st))
-> STM m (Maybe (RAWState st, st))
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (RAWState st -> Except SomeException (Maybe (RAWState st, st))
forall st.
RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireReadAccessPure RAWState st
rawSt) STM m (Maybe (RAWState st, st))
-> (Maybe (RAWState st, st) -> STM m st) -> STM m st
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (RAWState st, st)
Nothing -> STM m st
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
Just (RAWState st
rawSt', st
st) -> StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var RAWState st
rawSt' STM m () -> st -> STM m st
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> st
st
unsafeReleaseReadAccess :: IOLike m => RAWLock m st -> STM m ()
unsafeReleaseReadAccess :: RAWLock m st -> STM m ()
unsafeReleaseReadAccess (RAWLock StrictTVar m (RAWState st)
var) = do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (RAWState st -> Except SomeException (RAWState st)
forall st. RAWState st -> Except SomeException (RAWState st)
releaseReadAccessPure RAWState st
rawSt) STM m (RAWState st) -> (RAWState st -> STM m ()) -> STM m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var
unsafeAcquireAppendAccess :: IOLike m => RAWLock m st -> STM m st
unsafeAcquireAppendAccess :: RAWLock m st -> STM m st
unsafeAcquireAppendAccess (RAWLock StrictTVar m (RAWState st)
var) = do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (Maybe (RAWState st, st))
-> STM m (Maybe (RAWState st, st))
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (RAWState st -> Except SomeException (Maybe (RAWState st, st))
forall st.
RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireAppendAccessPure RAWState st
rawSt) STM m (Maybe (RAWState st, st))
-> (Maybe (RAWState st, st) -> STM m st) -> STM m st
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (RAWState st, st)
Nothing -> STM m st
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
Just (RAWState st
rawSt', st
st) -> StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var RAWState st
rawSt' STM m () -> st -> STM m st
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> st
st
unsafeReleaseAppendAccess
:: IOLike m
=> RAWLock m st
-> st
-> STM m ()
unsafeReleaseAppendAccess :: RAWLock m st -> st -> STM m ()
unsafeReleaseAppendAccess (RAWLock StrictTVar m (RAWState st)
var) st
st = do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (st -> RAWState st -> Except SomeException (RAWState st)
forall st. st -> RAWState st -> Except SomeException (RAWState st)
releaseAppendAccessPure st
st RAWState st
rawSt) STM m (RAWState st) -> (RAWState st -> STM m ()) -> STM m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var
unsafeAcquireWriteAccess :: IOLike m => RAWLock m st -> m st
unsafeAcquireWriteAccess :: RAWLock m st -> m st
unsafeAcquireWriteAccess rawLock :: RAWLock m st
rawLock@(RAWLock StrictTVar m (RAWState st)
var) = m (m st) -> m st
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (m (m st) -> m st) -> m (m st) -> m st
forall a b. (a -> b) -> a -> b
$ STM m (m st) -> m (m st)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (m st) -> m (m st)) -> STM m (m st) -> m (m st)
forall a b. (a -> b) -> a -> b
$ do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (Maybe (RAWState st, Maybe st))
-> STM m (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (RAWState st -> Except SomeException (Maybe (RAWState st, Maybe st))
forall st.
RAWState st -> Except SomeException (Maybe (RAWState st, Maybe st))
acquireWriteAccessPure RAWState st
rawSt) STM m (Maybe (RAWState st, Maybe st))
-> (Maybe (RAWState st, Maybe st) -> STM m (m st)) -> STM m (m st)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (RAWState st, Maybe st)
Nothing -> STM m (m st)
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
Just (RAWState st
rawSt', Maybe st
mbSt) -> do
StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var RAWState st
rawSt'
case Maybe st
mbSt of
Just st
st -> m st -> STM m (m st)
forall (m :: * -> *) a. Monad m => a -> m a
return (m st -> STM m (m st)) -> m st -> STM m (m st)
forall a b. (a -> b) -> a -> b
$ st -> m st
forall (m :: * -> *) a. Monad m => a -> m a
return st
st
Maybe st
Nothing -> m st -> STM m (m st)
forall (m :: * -> *) a. Monad m => a -> m a
return (m st -> STM m (m st)) -> m st -> STM m (m st)
forall a b. (a -> b) -> a -> b
$ RAWLock m st -> m st
forall (m :: * -> *) st. IOLike m => RAWLock m st -> m st
unsafeAcquireWriteAccess RAWLock m st
rawLock
unsafeReleaseWriteAccess
:: IOLike m
=> RAWLock m st
-> st
-> m ()
unsafeReleaseWriteAccess :: RAWLock m st -> st -> m ()
unsafeReleaseWriteAccess (RAWLock StrictTVar m (RAWState st)
var) st
st = STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
RAWState st
rawSt <- StrictTVar m (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (RAWState st)
var
Except SomeException (RAWState st) -> STM m (RAWState st)
forall (m :: * -> *) a.
MonadThrow m =>
Except SomeException a -> m a
withPoisoned (st -> RAWState st -> Except SomeException (RAWState st)
forall st. st -> RAWState st -> Except SomeException (RAWState st)
releaseWriteAccessPure st
st RAWState st
rawSt) STM m (RAWState st) -> (RAWState st -> STM m ()) -> STM m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= StrictTVar m (RAWState st) -> RAWState st -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (RAWState st)
var
newtype Readers = Readers Word
deriving newtype (Readers -> Readers -> Bool
(Readers -> Readers -> Bool)
-> (Readers -> Readers -> Bool) -> Eq Readers
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Readers -> Readers -> Bool
$c/= :: Readers -> Readers -> Bool
== :: Readers -> Readers -> Bool
$c== :: Readers -> Readers -> Bool
Eq, Eq Readers
Eq Readers
-> (Readers -> Readers -> Ordering)
-> (Readers -> Readers -> Bool)
-> (Readers -> Readers -> Bool)
-> (Readers -> Readers -> Bool)
-> (Readers -> Readers -> Bool)
-> (Readers -> Readers -> Readers)
-> (Readers -> Readers -> Readers)
-> Ord Readers
Readers -> Readers -> Bool
Readers -> Readers -> Ordering
Readers -> Readers -> Readers
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
min :: Readers -> Readers -> Readers
$cmin :: Readers -> Readers -> Readers
max :: Readers -> Readers -> Readers
$cmax :: Readers -> Readers -> Readers
>= :: Readers -> Readers -> Bool
$c>= :: Readers -> Readers -> Bool
> :: Readers -> Readers -> Bool
$c> :: Readers -> Readers -> Bool
<= :: Readers -> Readers -> Bool
$c<= :: Readers -> Readers -> Bool
< :: Readers -> Readers -> Bool
$c< :: Readers -> Readers -> Bool
compare :: Readers -> Readers -> Ordering
$ccompare :: Readers -> Readers -> Ordering
$cp1Ord :: Eq Readers
Ord, Int -> Readers
Readers -> Int
Readers -> [Readers]
Readers -> Readers
Readers -> Readers -> [Readers]
Readers -> Readers -> Readers -> [Readers]
(Readers -> Readers)
-> (Readers -> Readers)
-> (Int -> Readers)
-> (Readers -> Int)
-> (Readers -> [Readers])
-> (Readers -> Readers -> [Readers])
-> (Readers -> Readers -> [Readers])
-> (Readers -> Readers -> Readers -> [Readers])
-> Enum Readers
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Readers -> Readers -> Readers -> [Readers]
$cenumFromThenTo :: Readers -> Readers -> Readers -> [Readers]
enumFromTo :: Readers -> Readers -> [Readers]
$cenumFromTo :: Readers -> Readers -> [Readers]
enumFromThen :: Readers -> Readers -> [Readers]
$cenumFromThen :: Readers -> Readers -> [Readers]
enumFrom :: Readers -> [Readers]
$cenumFrom :: Readers -> [Readers]
fromEnum :: Readers -> Int
$cfromEnum :: Readers -> Int
toEnum :: Int -> Readers
$ctoEnum :: Int -> Readers
pred :: Readers -> Readers
$cpred :: Readers -> Readers
succ :: Readers -> Readers
$csucc :: Readers -> Readers
Enum, Integer -> Readers
Readers -> Readers
Readers -> Readers -> Readers
(Readers -> Readers -> Readers)
-> (Readers -> Readers -> Readers)
-> (Readers -> Readers -> Readers)
-> (Readers -> Readers)
-> (Readers -> Readers)
-> (Readers -> Readers)
-> (Integer -> Readers)
-> Num Readers
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Readers
$cfromInteger :: Integer -> Readers
signum :: Readers -> Readers
$csignum :: Readers -> Readers
abs :: Readers -> Readers
$cabs :: Readers -> Readers
negate :: Readers -> Readers
$cnegate :: Readers -> Readers
* :: Readers -> Readers -> Readers
$c* :: Readers -> Readers -> Readers
- :: Readers -> Readers -> Readers
$c- :: Readers -> Readers -> Readers
+ :: Readers -> Readers -> Readers
$c+ :: Readers -> Readers -> Readers
Num, Context -> Readers -> IO (Maybe ThunkInfo)
Proxy Readers -> String
(Context -> Readers -> IO (Maybe ThunkInfo))
-> (Context -> Readers -> IO (Maybe ThunkInfo))
-> (Proxy Readers -> String)
-> NoThunks Readers
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Readers -> String
$cshowTypeOf :: Proxy Readers -> String
wNoThunks :: Context -> Readers -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Readers -> IO (Maybe ThunkInfo)
noThunks :: Context -> Readers -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Readers -> IO (Maybe ThunkInfo)
NoThunks)
data Appender = NoAppender | Appender
deriving ((forall x. Appender -> Rep Appender x)
-> (forall x. Rep Appender x -> Appender) -> Generic Appender
forall x. Rep Appender x -> Appender
forall x. Appender -> Rep Appender x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Appender x -> Appender
$cfrom :: forall x. Appender -> Rep Appender x
Generic, Context -> Appender -> IO (Maybe ThunkInfo)
Proxy Appender -> String
(Context -> Appender -> IO (Maybe ThunkInfo))
-> (Context -> Appender -> IO (Maybe ThunkInfo))
-> (Proxy Appender -> String)
-> NoThunks Appender
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Appender -> String
$cshowTypeOf :: Proxy Appender -> String
wNoThunks :: Context -> Appender -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Appender -> IO (Maybe ThunkInfo)
noThunks :: Context -> Appender -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Appender -> IO (Maybe ThunkInfo)
NoThunks)
data RAWState st =
ReadAppend !Readers !Appender !st
| WaitingToWrite !Readers !Appender !st
| Writing
| Poisoned !(AllowThunk SomeException)
deriving ((forall x. RAWState st -> Rep (RAWState st) x)
-> (forall x. Rep (RAWState st) x -> RAWState st)
-> Generic (RAWState st)
forall x. Rep (RAWState st) x -> RAWState st
forall x. RAWState st -> Rep (RAWState st) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall st x. Rep (RAWState st) x -> RAWState st
forall st x. RAWState st -> Rep (RAWState st) x
$cto :: forall st x. Rep (RAWState st) x -> RAWState st
$cfrom :: forall st x. RAWState st -> Rep (RAWState st) x
Generic, Context -> RAWState st -> IO (Maybe ThunkInfo)
Proxy (RAWState st) -> String
(Context -> RAWState st -> IO (Maybe ThunkInfo))
-> (Context -> RAWState st -> IO (Maybe ThunkInfo))
-> (Proxy (RAWState st) -> String)
-> NoThunks (RAWState st)
forall st.
NoThunks st =>
Context -> RAWState st -> IO (Maybe ThunkInfo)
forall st. NoThunks st => Proxy (RAWState st) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (RAWState st) -> String
$cshowTypeOf :: forall st. NoThunks st => Proxy (RAWState st) -> String
wNoThunks :: Context -> RAWState st -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall st.
NoThunks st =>
Context -> RAWState st -> IO (Maybe ThunkInfo)
noThunks :: Context -> RAWState st -> IO (Maybe ThunkInfo)
$cnoThunks :: forall st.
NoThunks st =>
Context -> RAWState st -> IO (Maybe ThunkInfo)
NoThunks)
emptyRAWState :: st -> RAWState st
emptyRAWState :: st -> RAWState st
emptyRAWState = Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
ReadAppend (Word -> Readers
Readers Word
0) Appender
NoAppender
acquireReadAccessPure
:: RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireReadAccessPure :: RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireReadAccessPure = \case
ReadAppend Readers
readers Appender
appender st
st
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st)))
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall a b. (a -> b) -> a -> b
$ (RAWState st, st) -> Maybe (RAWState st, st)
forall a. a -> Maybe a
Just (Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
ReadAppend (Readers -> Readers
forall a. Enum a => a -> a
succ Readers
readers) Appender
appender st
st, st
st)
WaitingToWrite {}
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, st)
forall a. Maybe a
Nothing
RAWState st
Writing
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, st)
forall a. Maybe a
Nothing
Poisoned (AllowThunk SomeException
ex)
-> SomeException -> Except SomeException (Maybe (RAWState st, st))
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
releaseReadAccessPure
:: RAWState st -> Except SomeException (RAWState st)
releaseReadAccessPure :: RAWState st -> Except SomeException (RAWState st)
releaseReadAccessPure = \case
ReadAppend Readers
readers Appender
appender st
st
| Readers
0 <- Readers
readers
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing a reader without outstanding readers in ReadAppend"
| Bool
otherwise
-> RAWState st -> Except SomeException (RAWState st)
forall (m :: * -> *) a. Monad m => a -> m a
return (RAWState st -> Except SomeException (RAWState st))
-> RAWState st -> Except SomeException (RAWState st)
forall a b. (a -> b) -> a -> b
$ Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
ReadAppend (Readers -> Readers
forall a. Enum a => a -> a
pred Readers
readers) Appender
appender st
st
WaitingToWrite Readers
readers Appender
appender st
st
| Readers
0 <- Readers
readers
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing a reader without outstanding readers in WaitingToWrite"
| Bool
otherwise
-> RAWState st -> Except SomeException (RAWState st)
forall (m :: * -> *) a. Monad m => a -> m a
return (RAWState st -> Except SomeException (RAWState st))
-> RAWState st -> Except SomeException (RAWState st)
forall a b. (a -> b) -> a -> b
$ Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
WaitingToWrite (Readers -> Readers
forall a. Enum a => a -> a
pred Readers
readers) Appender
appender st
st
RAWState st
Writing
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing a reader without outstanding readers in Writing"
Poisoned (AllowThunk SomeException
ex)
-> SomeException -> Except SomeException (RAWState st)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
acquireAppendAccessPure
:: RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireAppendAccessPure :: RAWState st -> Except SomeException (Maybe (RAWState st, st))
acquireAppendAccessPure = \case
ReadAppend Readers
readers Appender
appender st
st
| Appender
NoAppender <- Appender
appender
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st)))
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall a b. (a -> b) -> a -> b
$ (RAWState st, st) -> Maybe (RAWState st, st)
forall a. a -> Maybe a
Just (Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
ReadAppend Readers
readers Appender
Appender st
st, st
st)
| Bool
otherwise
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, st)
forall a. Maybe a
Nothing
WaitingToWrite {}
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, st)
forall a. Maybe a
Nothing
RAWState st
Writing
-> Maybe (RAWState st, st)
-> Except SomeException (Maybe (RAWState st, st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, st)
forall a. Maybe a
Nothing
Poisoned (AllowThunk SomeException
ex)
-> SomeException -> Except SomeException (Maybe (RAWState st, st))
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
releaseAppendAccessPure
:: st -> RAWState st -> Except SomeException (RAWState st)
releaseAppendAccessPure :: st -> RAWState st -> Except SomeException (RAWState st)
releaseAppendAccessPure st
st' = \case
ReadAppend Readers
readers Appender
appender st
_st
| Appender
NoAppender <- Appender
appender
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing an appender without an outstanding appender in ReadAppend"
| Bool
otherwise
-> RAWState st -> Except SomeException (RAWState st)
forall (m :: * -> *) a. Monad m => a -> m a
return (RAWState st -> Except SomeException (RAWState st))
-> RAWState st -> Except SomeException (RAWState st)
forall a b. (a -> b) -> a -> b
$ Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
ReadAppend Readers
readers Appender
NoAppender st
st'
WaitingToWrite Readers
readers Appender
appender st
_st
| Appender
NoAppender <- Appender
appender
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing an appender without an outstanding appender in WaitingToWrite"
| Bool
otherwise
-> RAWState st -> Except SomeException (RAWState st)
forall (m :: * -> *) a. Monad m => a -> m a
return (RAWState st -> Except SomeException (RAWState st))
-> RAWState st -> Except SomeException (RAWState st)
forall a b. (a -> b) -> a -> b
$ Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
WaitingToWrite Readers
readers Appender
NoAppender st
st'
RAWState st
Writing
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing an appender without an outstanding appender in Writing"
Poisoned (AllowThunk SomeException
ex)
-> SomeException -> Except SomeException (RAWState st)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
acquireWriteAccessPure
:: RAWState st -> Except SomeException (Maybe (RAWState st, Maybe st))
acquireWriteAccessPure :: RAWState st -> Except SomeException (Maybe (RAWState st, Maybe st))
acquireWriteAccessPure = \case
ReadAppend Readers
readers Appender
appender st
st
| Readers
0 <- Readers
readers
, Appender
NoAppender <- Appender
appender
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st)))
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall a b. (a -> b) -> a -> b
$ (RAWState st, Maybe st) -> Maybe (RAWState st, Maybe st)
forall a. a -> Maybe a
Just (RAWState st
forall st. RAWState st
Writing, st -> Maybe st
forall a. a -> Maybe a
Just st
st)
| Bool
otherwise
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st)))
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall a b. (a -> b) -> a -> b
$ (RAWState st, Maybe st) -> Maybe (RAWState st, Maybe st)
forall a. a -> Maybe a
Just (Readers -> Appender -> st -> RAWState st
forall st. Readers -> Appender -> st -> RAWState st
WaitingToWrite Readers
readers Appender
appender st
st, Maybe st
forall a. Maybe a
Nothing)
WaitingToWrite Readers
readers Appender
appender st
st
| Readers
0 <- Readers
readers
, Appender
NoAppender <- Appender
appender
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st)))
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall a b. (a -> b) -> a -> b
$ (RAWState st, Maybe st) -> Maybe (RAWState st, Maybe st)
forall a. a -> Maybe a
Just (RAWState st
forall st. RAWState st
Writing, st -> Maybe st
forall a. a -> Maybe a
Just st
st)
| Bool
otherwise
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, Maybe st)
forall a. Maybe a
Nothing
RAWState st
Writing
-> Maybe (RAWState st, Maybe st)
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RAWState st, Maybe st)
forall a. Maybe a
Nothing
Poisoned (AllowThunk SomeException
ex)
-> SomeException
-> Except SomeException (Maybe (RAWState st, Maybe st))
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
releaseWriteAccessPure
:: st -> RAWState st -> Except SomeException (RAWState st)
releaseWriteAccessPure :: st -> RAWState st -> Except SomeException (RAWState st)
releaseWriteAccessPure st
st' = \case
ReadAppend Readers
_readers Appender
_appender st
_st
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing a writer in ReadAppend"
WaitingToWrite Readers
_readers Appender
_appender st
_st
-> String -> Except SomeException (RAWState st)
forall a. HasCallStack => String -> a
error String
"releasing a writer in WaitingToWrite"
RAWState st
Writing
-> RAWState st -> Except SomeException (RAWState st)
forall (m :: * -> *) a. Monad m => a -> m a
return (RAWState st -> Except SomeException (RAWState st))
-> RAWState st -> Except SomeException (RAWState st)
forall a b. (a -> b) -> a -> b
$ st -> RAWState st
forall st. st -> RAWState st
emptyRAWState st
st'
Poisoned (AllowThunk SomeException
ex)
-> SomeException -> Except SomeException (RAWState st)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
ex
poisonPure
:: SomeException -> RAWState st -> Except SomeException (RAWState st, Maybe st)
poisonPure :: SomeException
-> RAWState st -> Except SomeException (RAWState st, Maybe st)
poisonPure SomeException
ex = \case
ReadAppend Readers
_readers Appender
_appender st
st
-> (RAWState st, Maybe st)
-> Except SomeException (RAWState st, Maybe st)
forall (m :: * -> *) a. Monad m => a -> m a
return (AllowThunk SomeException -> RAWState st
forall st. AllowThunk SomeException -> RAWState st
Poisoned (SomeException -> AllowThunk SomeException
forall a. a -> AllowThunk a
AllowThunk SomeException
ex), st -> Maybe st
forall a. a -> Maybe a
Just st
st)
WaitingToWrite Readers
_readers Appender
_appender st
st
-> (RAWState st, Maybe st)
-> Except SomeException (RAWState st, Maybe st)
forall (m :: * -> *) a. Monad m => a -> m a
return (AllowThunk SomeException -> RAWState st
forall st. AllowThunk SomeException -> RAWState st
Poisoned (SomeException -> AllowThunk SomeException
forall a. a -> AllowThunk a
AllowThunk SomeException
ex), st -> Maybe st
forall a. a -> Maybe a
Just st
st)
RAWState st
Writing
-> (RAWState st, Maybe st)
-> Except SomeException (RAWState st, Maybe st)
forall (m :: * -> *) a. Monad m => a -> m a
return (AllowThunk SomeException -> RAWState st
forall st. AllowThunk SomeException -> RAWState st
Poisoned (SomeException -> AllowThunk SomeException
forall a. a -> AllowThunk a
AllowThunk SomeException
ex), Maybe st
forall a. Maybe a
Nothing)
Poisoned (AllowThunk SomeException
prevEx)
-> SomeException -> Except SomeException (RAWState st, Maybe st)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError SomeException
prevEx