{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Control.Concurrent.Class.MonadMVar.Strict.Checked
(
LazyMVar
, StrictMVar
, castStrictMVar
, fromLazyMVar
, isEmptyMVar
, modifyMVar
, modifyMVarMasked
, modifyMVarMasked_
, modifyMVar_
, newEmptyMVar
, newEmptyMVarWithInvariant
, newMVar
, newMVarWithInvariant
, putMVar
, readMVar
, swapMVar
, takeMVar
, toLazyMVar
, tryPutMVar
, tryReadMVar
, tryTakeMVar
, unsafeToUncheckedStrictMVar
, withMVar
, withMVarMasked
, checkInvariant
, MonadMVar
) where
import Control.Concurrent.Class.MonadMVar.Strict (LazyMVar, MonadMVar)
import Control.Concurrent.Class.MonadMVar.Strict qualified as Strict
import Data.Kind (Type)
import GHC.Stack (HasCallStack)
type StrictMVar :: (Type -> Type) -> Type -> Type
#if CHECK_MVAR_INVARIANTS
data StrictMVar m a = StrictMVar {
forall (m :: * -> *) a. StrictMVar m a -> a -> Maybe String
invariant :: !(a -> Maybe String)
, forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar :: !(Strict.StrictMVar m a)
}
#else
newtype StrictMVar m a = StrictMVar {
mvar :: Strict.StrictMVar m a
}
#endif
castStrictMVar ::
LazyMVar m ~ LazyMVar n =>
StrictMVar m a -> StrictMVar n a
castStrictMVar :: forall (m :: * -> *) (n :: * -> *) a.
(LazyMVar m ~ LazyMVar n) =>
StrictMVar m a -> StrictMVar n a
castStrictMVar StrictMVar m a
v = (a -> Maybe String) -> StrictMVar n a -> StrictMVar n a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar (StrictMVar m a -> a -> Maybe String
forall (m :: * -> *) a. StrictMVar m a -> a -> Maybe String
getInvariant StrictMVar m a
v) (StrictMVar m a -> StrictMVar n a
forall (m :: * -> *) (n :: * -> *) a.
(LazyMVar m ~ LazyMVar n) =>
StrictMVar m a -> StrictMVar n a
Strict.castStrictMVar (StrictMVar m a -> StrictMVar n a)
-> StrictMVar m a -> StrictMVar n a
forall a b. (a -> b) -> a -> b
$ StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
toLazyMVar :: StrictMVar m a -> LazyMVar m a
toLazyMVar :: forall (m :: * -> *) a. StrictMVar m a -> LazyMVar m a
toLazyMVar = StrictMVar m a -> MVar m a
forall (m :: * -> *) a. StrictMVar m a -> LazyMVar m a
Strict.toLazyMVar (StrictMVar m a -> MVar m a)
-> (StrictMVar m a -> StrictMVar m a) -> StrictMVar m a -> MVar m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar
fromLazyMVar :: LazyMVar m a -> StrictMVar m a
fromLazyMVar :: forall (m :: * -> *) a. LazyMVar m a -> StrictMVar m a
fromLazyMVar = (a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar (Maybe String -> a -> Maybe String
forall a b. a -> b -> a
const Maybe String
forall a. Maybe a
Nothing) (StrictMVar m a -> StrictMVar m a)
-> (MVar m a -> StrictMVar m a) -> MVar m a -> StrictMVar m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar m a -> StrictMVar m a
forall (m :: * -> *) a. MVar m a -> StrictMVar m a
Strict.fromLazyMVar
unsafeToUncheckedStrictMVar :: StrictMVar m a -> Strict.StrictMVar m a
unsafeToUncheckedStrictMVar :: forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
unsafeToUncheckedStrictMVar = StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar
newEmptyMVar :: MonadMVar m => m (StrictMVar m a)
newEmptyMVar :: forall (m :: * -> *) a. MonadMVar m => m (StrictMVar m a)
newEmptyMVar = (a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar (Maybe String -> a -> Maybe String
forall a b. a -> b -> a
const Maybe String
forall a. Maybe a
Nothing) (StrictMVar m a -> StrictMVar m a)
-> m (StrictMVar m a) -> m (StrictMVar m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (StrictMVar m a)
forall (m :: * -> *) a. MonadMVar m => m (StrictMVar m a)
Strict.newEmptyMVar
newEmptyMVarWithInvariant ::
MonadMVar m =>
(a -> Maybe String) ->
m (StrictMVar m a)
newEmptyMVarWithInvariant :: forall (m :: * -> *) a.
MonadMVar m =>
(a -> Maybe String) -> m (StrictMVar m a)
newEmptyMVarWithInvariant a -> Maybe String
inv = (a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar a -> Maybe String
inv (StrictMVar m a -> StrictMVar m a)
-> m (StrictMVar m a) -> m (StrictMVar m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (StrictMVar m a)
forall (m :: * -> *) a. MonadMVar m => m (StrictMVar m a)
Strict.newEmptyMVar
newMVar :: MonadMVar m => a -> m (StrictMVar m a)
newMVar :: forall (m :: * -> *) a. MonadMVar m => a -> m (StrictMVar m a)
newMVar a
a = (a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar (Maybe String -> a -> Maybe String
forall a b. a -> b -> a
const Maybe String
forall a. Maybe a
Nothing) (StrictMVar m a -> StrictMVar m a)
-> m (StrictMVar m a) -> m (StrictMVar m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> m (StrictMVar m a)
forall (m :: * -> *) a. MonadMVar m => a -> m (StrictMVar m a)
Strict.newMVar a
a
newMVarWithInvariant ::
(HasCallStack, MonadMVar m) =>
(a -> Maybe String) ->
a ->
m (StrictMVar m a)
newMVarWithInvariant :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
(a -> Maybe String) -> a -> m (StrictMVar m a)
newMVarWithInvariant a -> Maybe String
inv !a
a =
Maybe String -> m (StrictMVar m a) -> m (StrictMVar m a)
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (a -> Maybe String
inv a
a) (m (StrictMVar m a) -> m (StrictMVar m a))
-> m (StrictMVar m a) -> m (StrictMVar m a)
forall a b. (a -> b) -> a -> b
$
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar a -> Maybe String
inv (StrictMVar m a -> StrictMVar m a)
-> m (StrictMVar m a) -> m (StrictMVar m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> m (StrictMVar m a)
forall (m :: * -> *) a. MonadMVar m => a -> m (StrictMVar m a)
Strict.newMVar a
a
takeMVar :: MonadMVar m => StrictMVar m a -> m a
takeMVar :: forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m a
takeMVar = StrictMVar m a -> m a
forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m a
Strict.takeMVar (StrictMVar m a -> m a)
-> (StrictMVar m a -> StrictMVar m a) -> StrictMVar m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar
putMVar :: (HasCallStack, MonadMVar m) => StrictMVar m a -> a -> m ()
putMVar :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> a -> m ()
putMVar StrictMVar m a
v a
a = do
StrictMVar m a -> a -> m ()
forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> a -> m ()
Strict.putMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v) a
a
Maybe String -> m () -> m ()
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (StrictMVar m a -> a -> Maybe String
forall (m :: * -> *) a. StrictMVar m a -> a -> Maybe String
getInvariant StrictMVar m a
v a
a) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
readMVar :: MonadMVar m => StrictMVar m a -> m a
readMVar :: forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m a
readMVar StrictMVar m a
v = StrictMVar m a -> m a
forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m a
Strict.readMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
swapMVar :: (HasCallStack, MonadMVar m) => StrictMVar m a -> a -> m a
swapMVar :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> a -> m a
swapMVar StrictMVar m a
v a
a = do
oldValue <- StrictMVar m a -> a -> m a
forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> a -> m a
Strict.swapMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v) a
a
checkInvariant (getInvariant v a) $ pure oldValue
tryTakeMVar :: MonadMVar m => StrictMVar m a -> m (Maybe a)
tryTakeMVar :: forall (m :: * -> *) a.
MonadMVar m =>
StrictMVar m a -> m (Maybe a)
tryTakeMVar StrictMVar m a
v = StrictMVar m a -> m (Maybe a)
forall (m :: * -> *) a.
MonadMVar m =>
StrictMVar m a -> m (Maybe a)
Strict.tryTakeMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
tryPutMVar :: (HasCallStack, MonadMVar m) => StrictMVar m a -> a -> m Bool
tryPutMVar :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> a -> m Bool
tryPutMVar StrictMVar m a
v a
a = do
didPut <- StrictMVar m a -> a -> m Bool
forall (m :: * -> *) a.
MonadMVar m =>
StrictMVar m a -> a -> m Bool
Strict.tryPutMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v) a
a
checkInvariant (getInvariant v a) $ pure didPut
isEmptyMVar :: MonadMVar m => StrictMVar m a -> m Bool
isEmptyMVar :: forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m Bool
isEmptyMVar StrictMVar m a
v = StrictMVar m a -> m Bool
forall (m :: * -> *) a. MonadMVar m => StrictMVar m a -> m Bool
Strict.isEmptyMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
withMVar :: MonadMVar m => StrictMVar m a -> (a -> m b) -> m b
withMVar :: forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m b) -> m b
withMVar StrictMVar m a
v = StrictMVar m a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m b) -> m b
Strict.withMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
withMVarMasked :: MonadMVar m => StrictMVar m a -> (a -> m b) -> m b
withMVarMasked :: forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m b) -> m b
withMVarMasked StrictMVar m a
v = StrictMVar m a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m b) -> m b
Strict.withMVarMasked (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
modifyMVar_ ::
(HasCallStack, MonadMVar m) =>
StrictMVar m a ->
(a -> m a) ->
m ()
modifyMVar_ :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m a) -> m ()
modifyMVar_ StrictMVar m a
v a -> m a
io = StrictMVar m a -> (a -> m (a, ())) -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVar StrictMVar m a
v a -> m (a, ())
io'
where
io' :: a -> m (a, ())
io' a
a = (,()) (a -> (a, ())) -> m a -> m (a, ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> m a
io a
a
modifyMVar ::
(HasCallStack, MonadMVar m) =>
StrictMVar m a ->
(a -> m (a, b)) ->
m b
modifyMVar :: forall (m :: * -> *) a b.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVar StrictMVar m a
v a -> m (a, b)
io = do
(a', b) <- StrictMVar m a -> (a -> m (a, (a, b))) -> m (a, b)
forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m (a, b)) -> m b
Strict.modifyMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v) a -> m (a, (a, b))
io'
checkInvariant (getInvariant v a') $ pure b
where
io' :: a -> m (a, (a, b))
io' a
a = do
(a', b) <- a -> m (a, b)
io a
a
pure (a', (a', b))
modifyMVarMasked_ ::
(HasCallStack, MonadMVar m) =>
StrictMVar m a ->
(a -> m a) ->
m ()
modifyMVarMasked_ :: forall (m :: * -> *) a.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m a) -> m ()
modifyMVarMasked_ StrictMVar m a
v a -> m a
io = StrictMVar m a -> (a -> m (a, ())) -> m ()
forall (m :: * -> *) a b.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVarMasked StrictMVar m a
v a -> m (a, ())
io'
where
io' :: a -> m (a, ())
io' a
a = (,()) (a -> (a, ())) -> m a -> m (a, ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> m a
io a
a
modifyMVarMasked ::
(HasCallStack, MonadMVar m) =>
StrictMVar m a ->
(a -> m (a, b)) ->
m b
modifyMVarMasked :: forall (m :: * -> *) a b.
(HasCallStack, MonadMVar m) =>
StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVarMasked StrictMVar m a
v a -> m (a, b)
io = do
(a', b) <- StrictMVar m a -> (a -> m (a, (a, b))) -> m (a, b)
forall (m :: * -> *) a b.
MonadMVar m =>
StrictMVar m a -> (a -> m (a, b)) -> m b
Strict.modifyMVarMasked (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v) a -> m (a, (a, b))
io'
checkInvariant (getInvariant v a') $ pure b
where
io' :: a -> m (a, (a, b))
io' a
a = do
(a', b) <- a -> m (a, b)
io a
a
pure (a', (a', b))
tryReadMVar :: MonadMVar m => StrictMVar m a -> m (Maybe a)
tryReadMVar :: forall (m :: * -> *) a.
MonadMVar m =>
StrictMVar m a -> m (Maybe a)
tryReadMVar StrictMVar m a
v = StrictMVar m a -> m (Maybe a)
forall (m :: * -> *) a.
MonadMVar m =>
StrictMVar m a -> m (Maybe a)
Strict.tryReadMVar (StrictMVar m a -> StrictMVar m a
forall (m :: * -> *) a. StrictMVar m a -> StrictMVar m a
mvar StrictMVar m a
v)
checkInvariant :: HasCallStack => Maybe String -> a -> a
getInvariant :: StrictMVar m a -> a -> Maybe String
mkStrictMVar :: (a -> Maybe String) -> Strict.StrictMVar m a -> StrictMVar m a
#if CHECK_MVAR_INVARIANTS
checkInvariant :: forall a. HasCallStack => Maybe String -> a -> a
checkInvariant Maybe String
Nothing a
k = a
k
checkInvariant (Just String
err) a
_ = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"StrictMVar invariant violation: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err
getInvariant :: forall (m :: * -> *) a. StrictMVar m a -> a -> Maybe String
getInvariant StrictMVar {a -> Maybe String
invariant :: forall (m :: * -> *) a. StrictMVar m a -> a -> Maybe String
invariant :: a -> Maybe String
invariant} = a -> Maybe String
invariant
mkStrictMVar :: forall a (m :: * -> *).
(a -> Maybe String) -> StrictMVar m a -> StrictMVar m a
mkStrictMVar a -> Maybe String
invariant StrictMVar m a
mvar = StrictMVar {a -> Maybe String
invariant :: a -> Maybe String
invariant :: a -> Maybe String
invariant, StrictMVar m a
mvar :: StrictMVar m a
mvar :: StrictMVar m a
mvar}
#else
checkInvariant _err k = k
getInvariant _ = const Nothing
mkStrictMVar _invariant mvar = StrictMVar {mvar}
#endif