{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}

module Network.HTTP2.Server.Queue where

import Control.Concurrent (forkIO)
import Control.Concurrent.STM
import Control.Exception (bracket)
import Data.IORef

import Imports
import Network.HTTP2.Priority
import Network.HTTP2.Server.Manager
import Network.HTTP2.Server.Types

{-# INLINE forkAndEnqueueWhenReady #-}
forkAndEnqueueWhenReady :: IO () -> PriorityTree Output -> Output -> Manager -> IO ()
forkAndEnqueueWhenReady :: IO () -> PriorityTree Output -> Output -> Manager -> IO ()
forkAndEnqueueWhenReady wait :: IO ()
wait outQ :: PriorityTree Output
outQ out :: Output
out mgr :: Manager
mgr = IO () -> (() -> IO ()) -> (() -> IO ()) -> IO ()
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO ()
setup () -> IO ()
forall p. p -> IO ()
teardown ((() -> IO ()) -> IO ()) -> (() -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \_ ->
    IO ThreadId -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO ThreadId -> IO ()) -> (IO () -> IO ThreadId) -> IO () -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ThreadId
forkIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        IO ()
wait
        PriorityTree Output -> Output -> IO ()
enqueueOutput PriorityTree Output
outQ Output
out
  where
    setup :: IO ()
setup = Manager -> IO ()
addMyId Manager
mgr
    teardown :: p -> IO ()
teardown _ = Manager -> IO ()
deleteMyId Manager
mgr

{-# INLINE enqueueOutput #-}
enqueueOutput :: PriorityTree Output -> Output -> IO ()
enqueueOutput :: PriorityTree Output -> Output -> IO ()
enqueueOutput outQ :: PriorityTree Output
outQ out :: Output
out = do
    let Stream{..} = Output -> Stream
outputStream Output
out
    Precedence
pre <- IORef Precedence -> IO Precedence
forall a. IORef a -> IO a
readIORef IORef Precedence
streamPrecedence
    PriorityTree Output -> StreamId -> Precedence -> Output -> IO ()
forall a. PriorityTree a -> StreamId -> Precedence -> a -> IO ()
enqueue PriorityTree Output
outQ StreamId
streamNumber Precedence
pre Output
out

{-# INLINE enqueueControl #-}
enqueueControl :: TQueue Control -> Control -> IO ()
enqueueControl :: TQueue Control -> Control -> IO ()
enqueueControl ctlQ :: TQueue Control
ctlQ ctl :: Control
ctl = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue Control -> Control -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue TQueue Control
ctlQ Control
ctl

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