module Control.Concurrent.Classy.Chan
(
Chan
, newChan
, writeChan
, readChan
, dupChan
, writeList2Chan
) where
import Control.Concurrent.Classy.MVar
import Control.Monad.Catch (mask_)
import Control.Monad.Conc.Class (MonadConc)
data Chan m a
= Chan (MVar m (Stream m a))
(MVar m (Stream m a))
type Stream m a = MVar m (ChItem m a)
data ChItem m a = ChItem a (Stream m a)
newChan :: MonadConc m => m (Chan m a)
newChan :: forall (m :: * -> *) a. MonadConc m => m (Chan m a)
newChan = do
MVar m (ChItem m a)
hole <- forall (m :: * -> *) a. MonadConc m => m (MVar m a)
newEmptyMVar
MVar m (MVar m (ChItem m a))
readVar <- forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
newMVar MVar m (ChItem m a)
hole
MVar m (MVar m (ChItem m a))
writeVar <- forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
newMVar MVar m (ChItem m a)
hole
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall (m :: * -> *) a.
MVar m (Stream m a) -> MVar m (Stream m a) -> Chan m a
Chan MVar m (MVar m (ChItem m a))
readVar MVar m (MVar m (ChItem m a))
writeVar)
writeChan :: MonadConc m => Chan m a -> a -> m ()
writeChan :: forall (m :: * -> *) a. MonadConc m => Chan m a -> a -> m ()
writeChan (Chan MVar m (Stream m a)
_ MVar m (Stream m a)
writeVar) a
val = do
Stream m a
new_hole <- forall (m :: * -> *) a. MonadConc m => m (MVar m a)
newEmptyMVar
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ forall a b. (a -> b) -> a -> b
$ do
Stream m a
old_hole <- forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
takeMVar MVar m (Stream m a)
writeVar
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
putMVar Stream m a
old_hole (forall (m :: * -> *) a. a -> Stream m a -> ChItem m a
ChItem a
val Stream m a
new_hole)
forall (m :: * -> *) a. MonadConc m => MVar m a -> a -> m ()
putMVar MVar m (Stream m a)
writeVar Stream m a
new_hole
readChan :: MonadConc m => Chan m a -> m a
readChan :: forall (m :: * -> *) a. MonadConc m => Chan m a -> m a
readChan (Chan MVar m (Stream m a)
readVar MVar m (Stream m a)
_) = forall (m :: * -> *) a b.
MonadConc m =>
MVar m a -> (a -> m (a, b)) -> m b
modifyMVarMasked MVar m (Stream m a)
readVar forall a b. (a -> b) -> a -> b
$ \Stream m a
read_end -> do
(ChItem a
val Stream m a
new_read_end) <- forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
readMVar Stream m a
read_end
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Stream m a
new_read_end, a
val)
dupChan :: MonadConc m => Chan m a -> m (Chan m a)
dupChan :: forall (m :: * -> *) a. MonadConc m => Chan m a -> m (Chan m a)
dupChan (Chan MVar m (Stream m a)
_ MVar m (Stream m a)
writeVar) = do
Stream m a
hole <- forall (m :: * -> *) a. MonadConc m => MVar m a -> m a
readMVar MVar m (Stream m a)
writeVar
MVar m (Stream m a)
newReadVar <- forall (m :: * -> *) a. MonadConc m => a -> m (MVar m a)
newMVar Stream m a
hole
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall (m :: * -> *) a.
MVar m (Stream m a) -> MVar m (Stream m a) -> Chan m a
Chan MVar m (Stream m a)
newReadVar MVar m (Stream m a)
writeVar)
writeList2Chan :: MonadConc m => Chan m a -> [a] -> m ()
writeList2Chan :: forall (m :: * -> *) a. MonadConc m => Chan m a -> [a] -> m ()
writeList2Chan = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadConc m => Chan m a -> a -> m ()
writeChan