{-# LANGUAGE MagicHash #-}
module Effects.Concurrent.STM
(
STM,
MonadAtomic (..),
TVar,
newTVar',
readTVar',
writeTVar',
TVar.modifyTVar',
newTVarA',
readTVarA',
writeTVarA',
modifyTVarA',
TVar.newTVar,
TVar.readTVar,
TVar.writeTVar,
TVar.modifyTVar,
newTVarA,
readTVarA,
writeTVarA,
modifyTVarA,
TBQueue,
readTBQueue',
tryReadTBQueue',
writeTBQueue',
flushTBQueue',
readTBQueueA',
tryReadTBQueueA',
writeTBQueueA',
flushTBQueueA',
TBQueue.newTBQueue,
TBQueue.readTBQueue,
TBQueue.tryReadTBQueue,
TBQueue.writeTBQueue,
TBQueue.flushTBQueue,
newTBQueueA,
readTBQueueA,
tryReadTBQueueA,
writeTBQueueA,
flushTBQueueA,
Natural,
)
where
import Control.Concurrent.STM qualified as STM
import Control.Concurrent.STM.TBQueue (TBQueue)
import Control.Concurrent.STM.TBQueue qualified as TBQueue
import Control.Concurrent.STM.TVar (TVar)
import Control.Concurrent.STM.TVar qualified as TVar
import Control.Monad ((>=>))
import Control.Monad.Trans.Class (MonadTrans (lift))
import Control.Monad.Trans.Reader (ReaderT)
import GHC.Conc (STM (STM))
import GHC.Exts (seq#)
import GHC.Stack (HasCallStack)
import Numeric.Natural (Natural)
class (Monad m) => MonadAtomic m where
atomically :: (HasCallStack) => STM a -> m a
instance MonadAtomic IO where
atomically :: forall a. HasCallStack => STM a -> IO a
atomically = STM a -> IO a
forall a. STM a -> IO a
STM.atomically
{-# INLINEABLE atomically #-}
instance (MonadAtomic m) => MonadAtomic (ReaderT e m) where
atomically :: forall a. HasCallStack => STM a -> ReaderT e m a
atomically = m a -> ReaderT e m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT e m a) -> (STM a -> m a) -> STM a -> ReaderT e m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM a -> m a
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically
{-# INLINEABLE atomically #-}
newTVar' :: a -> STM (TVar a)
newTVar' :: forall a. a -> STM (TVar a)
newTVar' = a -> STM a
forall a. a -> STM a
evaluateSTM (a -> STM a) -> (a -> STM (TVar a)) -> a -> STM (TVar a)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> STM (TVar a)
forall a. a -> STM (TVar a)
TVar.newTVar
newTVarA :: (HasCallStack, MonadAtomic m) => a -> m (TVar a)
newTVarA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
a -> m (TVar a)
newTVarA = STM (TVar a) -> m (TVar a)
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM (TVar a) -> m (TVar a))
-> (a -> STM (TVar a)) -> a -> m (TVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> STM (TVar a)
forall a. a -> STM (TVar a)
TVar.newTVar
{-# INLINEABLE newTVarA #-}
newTVarA' :: (HasCallStack, MonadAtomic m) => a -> m (TVar a)
newTVarA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
a -> m (TVar a)
newTVarA' = STM (TVar a) -> m (TVar a)
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM (TVar a) -> m (TVar a))
-> (a -> STM (TVar a)) -> a -> m (TVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> STM (TVar a)
forall a. a -> STM (TVar a)
newTVar'
{-# INLINEABLE newTVarA' #-}
readTVar' :: TVar a -> STM a
readTVar' :: forall a. TVar a -> STM a
readTVar' = TVar a -> STM a
forall a. TVar a -> STM a
TVar.readTVar (TVar a -> STM a) -> (a -> STM a) -> TVar a -> STM a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> STM a
forall a. a -> STM a
evaluateSTM
readTVarA :: (HasCallStack, MonadAtomic m) => TVar a -> m a
readTVarA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> m a
readTVarA = STM a -> m a
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM a -> m a) -> (TVar a -> STM a) -> TVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> STM a
forall a. TVar a -> STM a
TVar.readTVar
{-# INLINEABLE readTVarA #-}
readTVarA' :: (HasCallStack, MonadAtomic m) => TVar a -> m a
readTVarA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> m a
readTVarA' = STM a -> m a
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM a -> m a) -> (TVar a -> STM a) -> TVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> STM a
forall a. TVar a -> STM a
readTVar'
{-# INLINEABLE readTVarA' #-}
writeTVar' :: TVar a -> a -> STM ()
writeTVar' :: forall a. TVar a -> a -> STM ()
writeTVar' TVar a
var = a -> STM a
forall a. a -> STM a
evaluateSTM (a -> STM a) -> (a -> STM ()) -> a -> STM ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
TVar.writeTVar TVar a
var
writeTVarA :: (HasCallStack, MonadAtomic m) => TVar a -> a -> m ()
writeTVarA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> a -> m ()
writeTVarA TVar a
r = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
TVar.writeTVar TVar a
r
{-# INLINEABLE writeTVarA #-}
writeTVarA' :: (HasCallStack, MonadAtomic m) => TVar a -> a -> m ()
writeTVarA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> a -> m ()
writeTVarA' TVar a
r = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar' TVar a
r
{-# INLINEABLE writeTVarA' #-}
modifyTVarA :: (HasCallStack, MonadAtomic m) => TVar a -> (a -> a) -> m ()
modifyTVarA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> (a -> a) -> m ()
modifyTVarA TVar a
r = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> ((a -> a) -> STM ()) -> (a -> a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> (a -> a) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
TVar.modifyTVar TVar a
r
{-# INLINEABLE modifyTVarA #-}
modifyTVarA' :: (HasCallStack, MonadAtomic m) => TVar a -> (a -> a) -> m ()
modifyTVarA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TVar a -> (a -> a) -> m ()
modifyTVarA' TVar a
r = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> ((a -> a) -> STM ()) -> (a -> a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> (a -> a) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
TVar.modifyTVar' TVar a
r
{-# INLINEABLE modifyTVarA' #-}
newTBQueueA ::
(HasCallStack, MonadAtomic m) =>
Natural ->
m (TBQueue a)
newTBQueueA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
Natural -> m (TBQueue a)
newTBQueueA = STM (TBQueue a) -> m (TBQueue a)
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM (TBQueue a) -> m (TBQueue a))
-> (Natural -> STM (TBQueue a)) -> Natural -> m (TBQueue a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> STM (TBQueue a)
forall a. Natural -> STM (TBQueue a)
TBQueue.newTBQueue
{-# INLINEABLE newTBQueueA #-}
readTBQueue' :: TBQueue a -> STM a
readTBQueue' :: forall a. TBQueue a -> STM a
readTBQueue' = TBQueue a -> STM a
forall a. TBQueue a -> STM a
TBQueue.readTBQueue (TBQueue a -> STM a) -> (a -> STM a) -> TBQueue a -> STM a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> STM a
forall a. a -> STM a
evaluateSTM
{-# INLINEABLE readTBQueue' #-}
readTBQueueA :: (HasCallStack, MonadAtomic m) => TBQueue a -> m a
readTBQueueA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m a
readTBQueueA = STM a -> m a
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM a -> m a) -> (TBQueue a -> STM a) -> TBQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
TBQueue.readTBQueue
{-# INLINEABLE readTBQueueA #-}
readTBQueueA' :: (HasCallStack, MonadAtomic m) => TBQueue a -> m a
readTBQueueA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m a
readTBQueueA' = STM a -> m a
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM a -> m a) -> (TBQueue a -> STM a) -> TBQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
readTBQueue'
{-# INLINEABLE readTBQueueA' #-}
tryReadTBQueue' :: TBQueue a -> STM (Maybe a)
tryReadTBQueue' :: forall a. TBQueue a -> STM (Maybe a)
tryReadTBQueue' =
TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
TBQueue.tryReadTBQueue (TBQueue a -> STM (Maybe a))
-> (Maybe a -> STM (Maybe a)) -> TBQueue a -> STM (Maybe a)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \case
Maybe a
Nothing -> Maybe a -> STM (Maybe a)
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
Just a
x -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> STM a -> STM (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> STM a
forall a. a -> STM a
evaluateSTM a
x
{-# INLINEABLE tryReadTBQueue' #-}
tryReadTBQueueA :: (HasCallStack, MonadAtomic m) => TBQueue a -> m (Maybe a)
tryReadTBQueueA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m (Maybe a)
tryReadTBQueueA = STM (Maybe a) -> m (Maybe a)
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM (Maybe a) -> m (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
TBQueue.tryReadTBQueue
{-# INLINEABLE tryReadTBQueueA #-}
tryReadTBQueueA' :: (HasCallStack, MonadAtomic m) => TBQueue a -> m (Maybe a)
tryReadTBQueueA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m (Maybe a)
tryReadTBQueueA' = STM (Maybe a) -> m (Maybe a)
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM (Maybe a) -> m (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
tryReadTBQueue'
{-# INLINEABLE tryReadTBQueueA' #-}
writeTBQueue' :: TBQueue a -> a -> STM ()
writeTBQueue' :: forall a. TBQueue a -> a -> STM ()
writeTBQueue' TBQueue a
q = a -> STM a
forall a. a -> STM a
evaluateSTM (a -> STM a) -> (a -> STM ()) -> a -> STM ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
TBQueue.writeTBQueue TBQueue a
q
writeTBQueueA :: (HasCallStack, MonadAtomic m) => TBQueue a -> a -> m ()
writeTBQueueA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> a -> m ()
writeTBQueueA TBQueue a
q = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
TBQueue.writeTBQueue TBQueue a
q
{-# INLINEABLE writeTBQueueA #-}
writeTBQueueA' :: (HasCallStack, MonadAtomic m) => TBQueue a -> a -> m ()
writeTBQueueA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> a -> m ()
writeTBQueueA' TBQueue a
q = STM () -> m ()
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
writeTBQueue' TBQueue a
q
{-# INLINEABLE writeTBQueueA' #-}
flushTBQueue' :: TBQueue a -> STM [a]
flushTBQueue' :: forall a. TBQueue a -> STM [a]
flushTBQueue' = TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
TBQueue.flushTBQueue (TBQueue a -> STM [a]) -> ([a] -> STM [a]) -> TBQueue a -> STM [a]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [a] -> STM [a]
forall a. a -> STM a
evaluateSTM
flushTBQueueA :: (HasCallStack, MonadAtomic m) => TBQueue a -> m [a]
flushTBQueueA :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m [a]
flushTBQueueA = STM [a] -> m [a]
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM [a] -> m [a]) -> (TBQueue a -> STM [a]) -> TBQueue a -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
TBQueue.flushTBQueue
{-# INLINEABLE flushTBQueueA #-}
flushTBQueueA' :: (HasCallStack, MonadAtomic m) => TBQueue a -> m [a]
flushTBQueueA' :: forall (m :: * -> *) a.
(HasCallStack, MonadAtomic m) =>
TBQueue a -> m [a]
flushTBQueueA' = STM [a] -> m [a]
forall a. HasCallStack => STM a -> m a
forall (m :: * -> *) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM [a] -> m [a]) -> (TBQueue a -> STM [a]) -> TBQueue a -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
flushTBQueue'
{-# INLINEABLE flushTBQueueA' #-}
evaluateSTM :: a -> STM a
evaluateSTM :: forall a. a -> STM a
evaluateSTM a
a = (State# RealWorld -> (# State# RealWorld, a #)) -> STM a
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> STM a
STM ((State# RealWorld -> (# State# RealWorld, a #)) -> STM a)
-> (State# RealWorld -> (# State# RealWorld, a #)) -> STM a
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> a -> State# RealWorld -> (# State# RealWorld, a #)
forall a s. a -> State# s -> (# State# s, a #)
seq# a
a State# RealWorld
s