module Brick.BChan
( BChan
, newBChan
, writeBChan
, writeBChanNonBlocking
, readBChan
, readBChan2
)
where
import Control.Concurrent.STM.TBQueue
import Control.Monad.STM (atomically, orElse)
data BChan a = BChan (TBQueue a)
newBChan :: Int
-> IO (BChan a)
newBChan :: forall a. Int -> IO (BChan a)
newBChan Int
size = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TBQueue a -> BChan a
BChan forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Natural -> STM (TBQueue a)
newTBQueue (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
writeBChan :: BChan a -> a -> IO ()
writeBChan :: forall a. BChan a -> a -> IO ()
writeBChan (BChan TBQueue a
q) a
a = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TBQueue a -> a -> STM ()
writeTBQueue TBQueue a
q a
a
writeBChanNonBlocking :: BChan a -> a -> IO Bool
writeBChanNonBlocking :: forall a. BChan a -> a -> IO Bool
writeBChanNonBlocking (BChan TBQueue a
q) a
a = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ do
Bool
f <- forall a. TBQueue a -> STM Bool
isFullTBQueue TBQueue a
q
if Bool
f
then forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else forall a. TBQueue a -> a -> STM ()
writeTBQueue TBQueue a
q a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
readBChan :: BChan a -> IO a
readBChan :: forall a. BChan a -> IO a
readBChan (BChan TBQueue a
q) = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TBQueue a -> STM a
readTBQueue TBQueue a
q
readBChan2 :: BChan a -> BChan b -> IO (Either a b)
readBChan2 :: forall a b. BChan a -> BChan b -> IO (Either a b)
readBChan2 (BChan TBQueue a
q1) (BChan TBQueue b
q2) = forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$
(forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. TBQueue a -> STM a
readTBQueue TBQueue a
q1) forall a. STM a -> STM a -> STM a
`orElse` (forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. TBQueue a -> STM a
readTBQueue TBQueue b
q2)