@@ -57,6 +57,8 @@ response ctx mgr tconf tickle strm sq s h strmbdy = do
5757
5858 runStream ctx OResponse tickle strm sq s h strmbdy
5959
60+-- | Set up a waiter thread and run the stream body with functions to enqueue
61+-- 'Sequence's on the stream's queue.
6062runStream :: Context
6163 -> (Stream -> H.Status -> H.ResponseHeaders -> Aux -> Output)
6264 -> Respond
@@ -68,14 +70,17 @@ runStream Context{outputQ} mkOutput tickle strm sq s h strmbdy = do
6870 -- queue is not empty.
6971 void $ forkIO $ waiter tvar sq strm outputQ
7072 atomically $ writeTVar tvar (SyncNext out)
71− let push chunk = do
73+ let write chunk = do
7274 atomically $ writeTBQueue sq $ case chunk of
7375 BuilderChunk b -> SBuilder b
7476 FileChunk path part -> SFile path part
7577 tickle
7678 flush = atomically $ writeTBQueue sq SFlush
77− strmbdy push flush
79+ strmbdy write flush
7880
81+-- | Set up a queue for the stream and use the given 'Respond' to actually run
82+-- it. This will be 'response' for client-initiated streams and just plain
83+-- 'runStream' for pushed streams.
7984runResponder :: Responder -> Respond -> IO () -> Stream -> IO ()
8085runResponder responder respond tickle strm = do
8186 -- Since 'Body' is loop, we cannot control it.
@@ -84,6 +89,8 @@ runResponder responder respond tickle strm = do
8489 trailers <- responder $ respond tickle strm sq
8590 atomically $ writeTBQueue sq $ SFinish trailers
8691
92+-- | Handle abnormal termination of a stream: mark it as closed, send a reset
93+-- frame, and call the user's 'settingsOnException' handler if applicable.
8794cleanupStream :: Context -> S.Settings -> Stream -> Maybe Request -> Maybe SomeException -> IO ()
8895cleanupStream Context{outputQ} set strm req me = do
8996 closed strm Killed
@@ -199,6 +206,11 @@ worker ctx@Context{inputQ} set tm app respond = do
199206 cleanupStream ctx set strm (Just req) me
200207 clearStreamInfo sinfo
201208
209+-- | A dedicated waiter thread to re-enqueue the stream in the priority tree
210+-- whenever output becomes available. When the sender drains the queue and
211+-- moves on to another stream, it drops a message in the 'TVar', and this
212+-- thread wakes up, waits for more output to become available, and re-enqueues
213+-- the stream.
202214waiter :: TVar Sync -> TBQueue Sequence -> Stream -> PriorityTree Output -> IO ()
203215waiter tvar sq strm outQ = do
204216 -- waiting for actions other than SyncNone