{-# LANGUAGE OverloadedStrings #-}

module Network.QUIC.Connection.Queue where

import Control.Concurrent.STM
import Network.Control (getRate)

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

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

takeInput :: Connection -> IO Input
takeInput :: Connection -> IO Input
takeInput Connection
conn = STM Input -> IO Input
forall a. STM a -> IO 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 a. STM a -> IO 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 a. STM a -> IO 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 a. STM a -> IO 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

isEmptyCryptoSTM :: Connection -> STM Bool
isEmptyCryptoSTM :: Connection -> STM Bool
isEmptyCryptoSTM Connection
conn = TQueue Crypto -> STM Bool
forall a. TQueue a -> STM Bool
isEmptyTQueue (TQueue Crypto -> STM Bool) -> TQueue Crypto -> STM Bool
forall a b. (a -> b) -> a -> b
$ Connection -> TQueue Crypto
cryptoQ Connection
conn

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

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 a. STM a -> IO 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 a. STM a -> IO 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 a. STM a -> IO 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

isEmptyOutputSTM :: Connection -> STM Bool
isEmptyOutputSTM :: Connection -> STM Bool
isEmptyOutputSTM Connection
conn = TQueue Output -> STM Bool
forall a. TQueue a -> STM Bool
isEmptyTQueue (TQueue Output -> STM Bool) -> TQueue Output -> STM Bool
forall a b. (a -> b) -> a -> b
$ Connection -> TQueue Output
outputQ Connection
conn

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

takeSendStreamQ :: Connection -> IO TxStreamData
takeSendStreamQ :: Connection -> IO TxStreamData
takeSendStreamQ Connection
conn = STM TxStreamData -> IO TxStreamData
forall a. STM a -> IO 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 a. STM a -> IO 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 a. STM a -> IO 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

isEmptyStreamSTM :: Connection -> STM Bool
isEmptyStreamSTM :: Connection -> STM Bool
isEmptyStreamSTM Connection
conn = TQueue TxStreamData -> STM Bool
forall a. TQueue a -> STM Bool
isEmptyTQueue (TQueue TxStreamData -> STM Bool)
-> TQueue TxStreamData -> STM Bool
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

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

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

rateOK :: Connection -> IO Bool
rateOK :: Connection -> IO Bool
rateOK Connection
conn = do
    Int
rate <- Rate -> IO Int
getRate (Rate -> IO Int) -> Rate -> IO Int
forall a b. (a -> b) -> a -> b
$ Connection -> Rate
outputRate Connection
conn
    Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Int
rate Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
outputLimit