module Network.QUIC.Connection.Queue where

import UnliftIO.STM

import Network.QUIC.Connection.Types
import Network.QUIC.Imports
import Network.QUIC.Stream
import Network.QUIC.Types

takeInput :: Connection -> IO Input
takeInput :: Connection -> IO Input
takeInput Connection
conn = STM Input -> IO Input
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM Input -> IO Input) -> STM Input -> IO Input
forall a b. (a -> b) -> a -> b
$ TQueue Input -> STM Input
forall a. TQueue a -> STM a
readTQueue (Connection -> TQueue Input
inputQ Connection
conn)

putInput :: Connection -> Input -> IO ()
putInput :: Connection -> Input -> IO ()
putInput Connection
conn Input
inp = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue Input -> Input -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue (Connection -> TQueue Input
inputQ Connection
conn) Input
inp

takeCrypto :: Connection -> IO Crypto
takeCrypto :: Connection -> IO Crypto
takeCrypto Connection
conn = STM Crypto -> IO Crypto
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM Crypto -> IO Crypto) -> STM Crypto -> IO Crypto
forall a b. (a -> b) -> a -> b
$ TQueue Crypto -> STM Crypto
forall a. TQueue a -> STM a
readTQueue (Connection -> TQueue Crypto
cryptoQ Connection
conn)

putCrypto :: Connection -> Crypto -> IO ()
putCrypto :: Connection -> Crypto -> IO ()
putCrypto Connection
conn Crypto
inp = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue Crypto -> Crypto -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue (Connection -> TQueue Crypto
cryptoQ Connection
conn) Crypto
inp

takeOutputSTM :: Connection -> STM Output
takeOutputSTM :: Connection -> STM Output
takeOutputSTM Connection
conn = TQueue Output -> STM Output
forall a. TQueue a -> STM a
readTQueue (Connection -> TQueue Output
outputQ Connection
conn)

tryTakeOutput :: Connection -> IO (Maybe Output)
tryTakeOutput :: Connection -> IO (Maybe Output)
tryTakeOutput Connection
conn = STM (Maybe Output) -> IO (Maybe Output)
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM (Maybe Output) -> IO (Maybe Output))
-> STM (Maybe Output) -> IO (Maybe Output)
forall a b. (a -> b) -> a -> b
$ TQueue Output -> STM (Maybe Output)
forall a. TQueue a -> STM (Maybe a)
tryReadTQueue (Connection -> TQueue Output
outputQ Connection
conn)

tryPeekOutput :: Connection -> IO (Maybe Output)
tryPeekOutput :: Connection -> IO (Maybe Output)
tryPeekOutput Connection
conn = STM (Maybe Output) -> IO (Maybe Output)
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM (Maybe Output) -> IO (Maybe Output))
-> STM (Maybe Output) -> IO (Maybe Output)
forall a b. (a -> b) -> a -> b
$ TQueue Output -> STM (Maybe Output)
forall a. TQueue a -> STM (Maybe a)
tryPeekTQueue (Connection -> TQueue Output
outputQ Connection
conn)

putOutput :: Connection -> Output -> IO ()
putOutput :: Connection -> Output -> IO ()
putOutput Connection
conn Output
out = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue Output -> Output -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue (Connection -> TQueue Output
outputQ Connection
conn) Output
out

outputLimit :: Int
outputLimit :: Int
outputLimit = Int
10

putOutputLim :: Connection -> Output -> IO ()
putOutputLim :: Connection -> Output -> IO ()
putOutputLim Connection
conn Output
out = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    Int
len <- Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Int) -> STM Natural -> STM Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TBQueue Output -> STM Natural
forall a. TBQueue a -> STM Natural
lengthTBQueue (Connection -> TBQueue Output
outputQLim Connection
conn)
    -- unless ok, the frames are intentionally dropped.
    Bool -> STM () -> STM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
outputLimit) (STM () -> STM ()) -> STM () -> STM ()
forall a b. (a -> b) -> a -> b
$ TBQueue Output -> Output -> STM ()
forall a. TBQueue a -> a -> STM ()
writeTBQueue (Connection -> TBQueue Output
outputQLim Connection
conn) Output
out

takeOutput1STM :: Connection -> STM Output
takeOutput1STM :: Connection -> STM Output
takeOutput1STM Connection
conn = TBQueue Output -> STM Output
forall a. TBQueue a -> STM a
readTBQueue (Connection -> TBQueue Output
outputQLim Connection
conn)

----------------------------------------------------------------

takeSendStreamQ :: Connection -> IO TxStreamData
takeSendStreamQ :: Connection -> IO TxStreamData
takeSendStreamQ Connection
conn = STM TxStreamData -> IO TxStreamData
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM TxStreamData -> IO TxStreamData)
-> STM TxStreamData -> IO TxStreamData
forall a b. (a -> b) -> a -> b
$ TQueue TxStreamData -> STM TxStreamData
forall a. TQueue a -> STM a
readTQueue (TQueue TxStreamData -> STM TxStreamData)
-> TQueue TxStreamData -> STM TxStreamData
forall a b. (a -> b) -> a -> b
$ Shared -> TQueue TxStreamData
sharedSendStreamQ (Shared -> TQueue TxStreamData) -> Shared -> TQueue TxStreamData
forall a b. (a -> b) -> a -> b
$ Connection -> Shared
shared Connection
conn

takeSendStreamQSTM :: Connection -> STM TxStreamData
takeSendStreamQSTM :: Connection -> STM TxStreamData
takeSendStreamQSTM Connection
conn = TQueue TxStreamData -> STM TxStreamData
forall a. TQueue a -> STM a
readTQueue (TQueue TxStreamData -> STM TxStreamData)
-> TQueue TxStreamData -> STM TxStreamData
forall a b. (a -> b) -> a -> b
$ Shared -> TQueue TxStreamData
sharedSendStreamQ (Shared -> TQueue TxStreamData) -> Shared -> TQueue TxStreamData
forall a b. (a -> b) -> a -> b
$ Connection -> Shared
shared Connection
conn

tryPeekSendStreamQ :: Connection -> IO (Maybe TxStreamData)
tryPeekSendStreamQ :: Connection -> IO (Maybe TxStreamData)
tryPeekSendStreamQ Connection
conn = STM (Maybe TxStreamData) -> IO (Maybe TxStreamData)
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM (Maybe TxStreamData) -> IO (Maybe TxStreamData))
-> STM (Maybe TxStreamData) -> IO (Maybe TxStreamData)
forall a b. (a -> b) -> a -> b
$ TQueue TxStreamData -> STM (Maybe TxStreamData)
forall a. TQueue a -> STM (Maybe a)
tryPeekTQueue (TQueue TxStreamData -> STM (Maybe TxStreamData))
-> TQueue TxStreamData -> STM (Maybe TxStreamData)
forall a b. (a -> b) -> a -> b
$ Shared -> TQueue TxStreamData
sharedSendStreamQ (Shared -> TQueue TxStreamData) -> Shared -> TQueue TxStreamData
forall a b. (a -> b) -> a -> b
$ Connection -> Shared
shared Connection
conn

putSendStreamQ :: Connection -> TxStreamData -> IO ()
putSendStreamQ :: Connection -> TxStreamData -> IO ()
putSendStreamQ Connection
conn TxStreamData
out = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue TxStreamData -> TxStreamData -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue (Shared -> TQueue TxStreamData
sharedSendStreamQ (Shared -> TQueue TxStreamData) -> Shared -> TQueue TxStreamData
forall a b. (a -> b) -> a -> b
$ Connection -> Shared
shared Connection
conn) TxStreamData
out

----------------------------------------------------------------

readMigrationQ :: Connection -> IO ReceivedPacket
readMigrationQ :: Connection -> IO ReceivedPacket
readMigrationQ Connection
conn = STM ReceivedPacket -> IO ReceivedPacket
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM ReceivedPacket -> IO ReceivedPacket)
-> STM ReceivedPacket -> IO ReceivedPacket
forall a b. (a -> b) -> a -> b
$ TQueue ReceivedPacket -> STM ReceivedPacket
forall a. TQueue a -> STM a
readTQueue (TQueue ReceivedPacket -> STM ReceivedPacket)
-> TQueue ReceivedPacket -> STM ReceivedPacket
forall a b. (a -> b) -> a -> b
$ Connection -> TQueue ReceivedPacket
migrationQ Connection
conn

writeMigrationQ :: Connection -> ReceivedPacket -> IO ()
writeMigrationQ :: Connection -> ReceivedPacket -> IO ()
writeMigrationQ Connection
conn ReceivedPacket
x = STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue ReceivedPacket -> ReceivedPacket -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue (Connection -> TQueue ReceivedPacket
migrationQ Connection
conn) ReceivedPacket
x