{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TypeOperators #-}
module Control.Concurrent.Class.MonadSTM.Strict.TVar
(
StrictTVar
, LazyTVar
, toLazyTVar
, fromLazyTVar
, castStrictTVar
, newTVar
, newTVarIO
, newTVarWithInvariant
, newTVarWithInvariantIO
, readTVar
, readTVarIO
, writeTVar
, modifyTVar
, stateTVar
, swapTVar
, check
, checkInvariant
, labelTVar
, labelTVarIO
, traceTVar
, traceTVarIO
) where
import qualified Control.Concurrent.Class.MonadSTM.TVar as Lazy
import Control.Monad.Class.MonadSTM hiding (traceTVar, traceTVarIO)
import GHC.Stack
type LazyTVar m = Lazy.TVar m
#if CHECK_TVAR_INVARIANT
data StrictTVar m a = StrictTVar
{ invariant :: !(a -> Maybe String)
, tvar :: !(LazyTVar m a)
}
#else
newtype StrictTVar m a = StrictTVar
{ forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar :: LazyTVar m a
}
#endif
labelTVar :: MonadLabelledSTM m => StrictTVar m a -> String -> STM m ()
labelTVar :: forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTVar m a -> String -> STM m ()
labelTVar StrictTVar { LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar } = forall (m :: * -> *) a.
MonadLabelledSTM m =>
TVar m a -> String -> STM m ()
Lazy.labelTVar LazyTVar m a
tvar
labelTVarIO :: MonadLabelledSTM m => StrictTVar m a -> String -> m ()
labelTVarIO :: forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTVar m a -> String -> m ()
labelTVarIO StrictTVar m a
v = forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTVar m a -> String -> STM m ()
labelTVar StrictTVar m a
v
traceTVar :: MonadTraceSTM m
=> proxy m
-> StrictTVar m a
-> (Maybe a -> a -> InspectMonad m TraceValue)
-> STM m ()
traceTVar :: forall (m :: * -> *) (proxy :: (* -> *) -> *) a.
MonadTraceSTM m =>
proxy m
-> StrictTVar m a
-> (Maybe a -> a -> InspectMonad m TraceValue)
-> STM m ()
traceTVar proxy m
p StrictTVar {LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar} = forall (m :: * -> *) (proxy :: (* -> *) -> *) a.
MonadTraceSTM m =>
proxy m
-> TVar m a
-> (Maybe a -> a -> InspectMonad m TraceValue)
-> STM m ()
Lazy.traceTVar proxy m
p LazyTVar m a
tvar
traceTVarIO :: MonadTraceSTM m
=> StrictTVar m a
-> (Maybe a -> a -> InspectMonad m TraceValue)
-> m ()
traceTVarIO :: forall (m :: * -> *) a.
MonadTraceSTM m =>
StrictTVar m a
-> (Maybe a -> a -> InspectMonad m TraceValue) -> m ()
traceTVarIO StrictTVar {LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar} = forall (m :: * -> *) a.
MonadTraceSTM m =>
TVar m a -> (Maybe a -> a -> InspectMonad m TraceValue) -> m ()
Lazy.traceTVarIO LazyTVar m a
tvar
castStrictTVar :: LazyTVar m ~ LazyTVar n
=> StrictTVar m a -> StrictTVar n a
castStrictTVar :: forall (m :: * -> *) (n :: * -> *) a.
(LazyTVar m ~ LazyTVar n) =>
StrictTVar m a -> StrictTVar n a
castStrictTVar v :: StrictTVar m a
v@StrictTVar {LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar} =
forall a (m :: * -> *).
(a -> Maybe String) -> TVar m a -> StrictTVar m a
mkStrictTVar (forall (m :: * -> *) a. StrictTVar m a -> a -> Maybe String
getInvariant StrictTVar m a
v) LazyTVar m a
tvar
toLazyTVar :: StrictTVar m a -> LazyTVar m a
toLazyTVar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
toLazyTVar StrictTVar { LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar } = LazyTVar m a
tvar
fromLazyTVar :: LazyTVar m a -> StrictTVar m a
fromLazyTVar :: forall (m :: * -> *) a. LazyTVar m a -> StrictTVar m a
fromLazyTVar LazyTVar m a
tvar =
#if CHECK_TVAR_INVARIANT
StrictTVar { invariant = const Nothing
, tvar
}
#else
StrictTVar { LazyTVar m a
tvar :: LazyTVar m a
tvar :: LazyTVar m a
tvar }
#endif
newTVar :: MonadSTM m => a -> STM m (StrictTVar m a)
newTVar :: forall (m :: * -> *) a. MonadSTM m => a -> STM m (StrictTVar m a)
newTVar !a
a = (\TVar m a
tvar -> forall a (m :: * -> *).
(a -> Maybe String) -> TVar m a -> StrictTVar m a
mkStrictTVar (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) TVar m a
tvar)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadSTM m => a -> STM m (TVar m a)
Lazy.newTVar a
a
newTVarIO :: MonadSTM m => a -> m (StrictTVar m a)
newTVarIO :: forall (m :: * -> *) a. MonadSTM m => a -> m (StrictTVar m a)
newTVarIO = forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictTVar m a)
newTVarWithInvariantIO (forall a b. a -> b -> a
const forall a. Maybe a
Nothing)
newTVarWithInvariant :: (MonadSTM m, HasCallStack)
=> (a -> Maybe String)
-> a
-> STM m (StrictTVar m a)
newTVarWithInvariant :: forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> STM m (StrictTVar m a)
newTVarWithInvariant a -> Maybe String
invariant !a
a =
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (a -> Maybe String
invariant a
a) forall a b. (a -> b) -> a -> b
$
(\TVar m a
tvar -> forall a (m :: * -> *).
(a -> Maybe String) -> TVar m a -> StrictTVar m a
mkStrictTVar a -> Maybe String
invariant TVar m a
tvar)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadSTM m => a -> STM m (TVar m a)
Lazy.newTVar a
a
newTVarWithInvariantIO :: (MonadSTM m, HasCallStack)
=> (a -> Maybe String)
-> a
-> m (StrictTVar m a)
newTVarWithInvariantIO :: forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictTVar m a)
newTVarWithInvariantIO a -> Maybe String
invariant !a
a =
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (a -> Maybe String
invariant a
a) forall a b. (a -> b) -> a -> b
$
(\TVar m a
tvar -> forall a (m :: * -> *).
(a -> Maybe String) -> TVar m a -> StrictTVar m a
mkStrictTVar a -> Maybe String
invariant TVar m a
tvar)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadSTM m => a -> m (TVar m a)
Lazy.newTVarIO a
a
readTVar :: MonadSTM m => StrictTVar m a -> STM m a
readTVar :: forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar { LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar } = forall (m :: * -> *) a. MonadSTM m => TVar m a -> STM m a
Lazy.readTVar LazyTVar m a
tvar
readTVarIO :: MonadSTM m => StrictTVar m a -> m a
readTVarIO :: forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> m a
readTVarIO StrictTVar { LazyTVar m a
tvar :: LazyTVar m a
tvar :: forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar } = forall (m :: * -> *) a. MonadSTM m => TVar m a -> m a
Lazy.readTVarIO LazyTVar m a
tvar
writeTVar :: (MonadSTM m, HasCallStack) => StrictTVar m a -> a -> STM m ()
writeTVar :: forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m a
v !a
a =
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (forall (m :: * -> *) a. StrictTVar m a -> a -> Maybe String
getInvariant StrictTVar m a
v a
a) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadSTM m => TVar m a -> a -> STM m ()
Lazy.writeTVar (forall (m :: * -> *) a. StrictTVar m a -> LazyTVar m a
tvar StrictTVar m a
v) a
a
modifyTVar :: MonadSTM m => StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar :: forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m a
v a -> a
f = forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m a
v forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m a
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f
stateTVar :: MonadSTM m => StrictTVar m s -> (s -> (a, s)) -> STM m a
stateTVar :: forall (m :: * -> *) s a.
MonadSTM m =>
StrictTVar m s -> (s -> (a, s)) -> STM m a
stateTVar StrictTVar m s
v s -> (a, s)
f = do
s
a <- forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m s
v
let (a
b, s
a') = s -> (a, s)
f s
a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m s
v s
a'
forall (m :: * -> *) a. Monad m => a -> m a
return a
b
swapTVar :: MonadSTM m => StrictTVar m a -> a -> STM m a
swapTVar :: forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> a -> STM m a
swapTVar StrictTVar m a
v a
a' = do
a
a <- forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m a
v
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m a
v a
a'
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
getInvariant :: StrictTVar m a -> a -> Maybe String
mkStrictTVar :: (a -> Maybe String) -> Lazy.TVar m a -> StrictTVar m a
checkInvariant :: HasCallStack => Maybe String -> a -> a
#if CHECK_TVAR_INVARIANT
getInvariant StrictTVar {invariant} = invariant
mkStrictTVar invariant tvar = StrictTVar {invariant, tvar}
checkInvariant Nothing k = k
checkInvariant (Just err) _ = error $ "Invariant violation: " ++ err
#else
getInvariant :: forall (m :: * -> *) a. StrictTVar m a -> a -> Maybe String
getInvariant StrictTVar m a
_ = \a
_ -> forall a. Maybe a
Nothing
mkStrictTVar :: forall a (m :: * -> *).
(a -> Maybe String) -> TVar m a -> StrictTVar m a
mkStrictTVar a -> Maybe String
_invariant TVar m a
tvar = StrictTVar {TVar m a
tvar :: TVar m a
tvar :: TVar m a
tvar}
checkInvariant :: forall a. HasCallStack => Maybe String -> a -> a
checkInvariant Maybe String
_err a
k = a
k
#endif