@@ -107,11 +107,11 @@ frameSender ctx@Context{outputQ,connectionWindow,encodeDynamicTable}
107 switch out@(OResponse strm rsp binfo) pre = do
107 switch out@(OResponse strm rsp binfo) pre = do
108 writeIORef (streamPrecedence strm) pre
108 writeIORef (streamPrecedence strm) pre
109 unlessClosed ctx conn strm $ do
109 unlessClosed ctx conn strm $ do
110− cws <- getConnectionWindowSizeWhenReady ctx
111 sws <- getStreamWindowSize strm
110 sws <- getStreamWindowSize strm
112 if sws == 0 then do
111 if sws == 0 then do
113 enqueueWhenReady (waitStreamWindowSize strm) outputQ out
112 enqueueWhenReady (waitStreamWindowSize strm) outputQ out
114+ cws <- getConnectionWindowSizeWhenReady ctx
115 let !lim = min cws sws
115 let !lim = min cws sws
116 -- Header frame and Continuation frame
116 -- Header frame and Continuation frame
117 let sid = streamNumber strm
117 let sid = streamNumber strm
@@ -129,7 +129,7 @@ frameSender ctx@Context{outputQ,connectionWindow,encodeDynamicTable}
129 Next datPayloadLen mnext <-
129 Next datPayloadLen mnext <-
130 fillResponseBodyGetNext conn ii payloadOff lim rsp
130 fillResponseBodyGetNext conn ii payloadOff lim rsp
131 fillDataHeaderSend strm total datPayloadLen mnext
131 fillDataHeaderSend strm total datPayloadLen mnext
132− maybeEnqueueNext strm mnext
132+ maybeEnqueueNext strm mnext binfo
133 OneshotWithoutBody -> do
133 OneshotWithoutBody -> do
134 -- "closed" must be before "connSendAll". If not,
134 -- "closed" must be before "connSendAll". If not,
135 -- the context would be switched to the receiver,
135 -- the context would be switched to the receiver,
@@ -147,21 +147,21 @@ frameSender ctx@Context{outputQ,connectionWindow,encodeDynamicTable}
147 fillDataHeaderSend strm total datPayloadLen mnext
147 fillDataHeaderSend strm total datPayloadLen mnext
149 when needSend $ flushN off
149 when needSend $ flushN off
150− maybeEnqueueNext strm mnext
150+ maybeEnqueueNext strm mnext binfo
152− switch out@(ONext strm curr) pre = do
152+ switch out@(ONext strm curr binfo) pre = do
153 writeIORef (streamPrecedence strm) pre
153 writeIORef (streamPrecedence strm) pre
154 unlessClosed ctx conn strm $ do
154 unlessClosed ctx conn strm $ do
155− cws <- getConnectionWindowSizeWhenReady ctx
156 sws <- getStreamWindowSize strm
155 sws <- getStreamWindowSize strm
157 if sws == 0 then do
156 if sws == 0 then do
158 enqueueWhenReady (waitStreamWindowSize strm) outputQ out
157 enqueueWhenReady (waitStreamWindowSize strm) outputQ out
159+ cws <- getConnectionWindowSizeWhenReady ctx
160 let !lim = min cws sws
160 let !lim = min cws sws
161 -- Data frame payload
161 -- Data frame payload
162 Next datPayloadLen mnext <- curr lim
162 Next datPayloadLen mnext <- curr lim
163 fillDataHeaderSend strm 0 datPayloadLen mnext
163 fillDataHeaderSend strm 0 datPayloadLen mnext
164− maybeEnqueueNext strm mnext
164+ maybeEnqueueNext strm mnext binfo
167 -- Flush the connection buffer to the socket, where the first 'n' bytes of
167 -- Flush the connection buffer to the socket, where the first 'n' bytes of
@@ -202,16 +202,12 @@ frameSender ctx@Context{outputQ,connectionWindow,encodeDynamicTable}
202 -- True if the connection buffer has room for a 1-byte data frame.
202 -- True if the connection buffer has room for a 1-byte data frame.
203 canFitDataFrame total = total + frameHeaderLength < connBufferSize
203 canFitDataFrame total = total + frameHeaderLength < connBufferSize
205− -- Re-enqueue the stream in the output queue if more output is immediately
205+ -- Re-enqueue the stream in the output queue.
206− -- available; do nothing otherwise.
207− maybeEnqueueNext :: Stream -> Control DynaNext -> IO ()
206+ maybeEnqueueNext :: Stream -> Maybe DynaNext -> BodyInfo -> IO ()
208− maybeEnqueueNext strm (CNext next) = do
207+ maybeEnqueueNext strm (Just next) binfo = do
209− let out = ONext strm next
208+ let !out = ONext strm next binfo
210 enqueueOutput outputQ out
209 enqueueOutput outputQ out
211− -- If the streaming is not finished, it must already have been
212− -- written to the 'TVar' owned by 'waiter', which will
213− -- put it back into the queue when more output becomes available.
214− maybeEnqueueNext _ _ = return ()
210+ maybeEnqueueNext _ _ _ = return ()
217 -- Send headers if there is not room for a 1-byte data frame, and return
213 -- Send headers if there is not room for a 1-byte data frame, and return
@@ -229,15 +225,15 @@ frameSender ctx@Context{outputQ,connectionWindow,encodeDynamicTable}
229 buf = connWriteBuffer `plusPtr` otherLen
225 buf = connWriteBuffer `plusPtr` otherLen
230 total = otherLen + frameHeaderLength + datPayloadLen
226 total = otherLen + frameHeaderLength + datPayloadLen
231 flag = case mnext of
227 flag = case mnext of
232− CFinish -> setEndStream defaultFlags
228+ Nothing -> setEndStream defaultFlags
233 _ -> defaultFlags
229 _ -> defaultFlags
234 fillFrameHeader FrameData datPayloadLen sid flag buf
230 fillFrameHeader FrameData datPayloadLen sid flag buf
235 -- "closed" must be before "connSendAll". If not,
231 -- "closed" must be before "connSendAll". If not,
236 -- the context would be switched to the receiver,
232 -- the context would be switched to the receiver,
237 -- resulting the inconsistency of concurrency.
233 -- resulting the inconsistency of concurrency.
238 case mnext of
234 case mnext of
239− CFinish -> closed ctx strm Finished
235+ Nothing -> closed ctx strm Finished
240− _ -> return ()
236+ _ -> return ()
241 flushN total
237 flushN total
242 atomically $ do
238 atomically $ do
243 modifyTVar' connectionWindow (subtract datPayloadLen)
239 modifyTVar' connectionWindow (subtract datPayloadLen)
@@ -337,11 +333,11 @@ fillBufBuilder buf0 siz0 leftover lim = do
338nextForBuilder :: Buffer -> BufSize -> BytesFilled -> B.Next -> Next
334nextForBuilder :: Buffer -> BufSize -> BytesFilled -> B.Next -> Next
339nextForBuilder _ _ len B.Done
335nextForBuilder _ _ len B.Done
340− = Next len CFinish
336+ = Next len Nothing
341nextForBuilder buf siz len (B.More _ writer)
337nextForBuilder buf siz len (B.More _ writer)
342− = Next len (CNext (fillBufBuilder buf siz (LOne writer)))
338+ = Next len $ Just (fillBufBuilder buf siz (LOne writer))
343nextForBuilder buf siz len (B.Chunk bs writer)
339nextForBuilder buf siz len (B.Chunk bs writer)
344− = Next len (CNext (fillBufBuilder buf siz (LTwo bs writer)))
340+ = Next len $ Just (fillBufBuilder buf siz (LTwo bs writer))
346----------------------------------------------------------------
342----------------------------------------------------------------
@@ -400,9 +396,9 @@ fillBufStream buf0 siz0 leftover0 sq strm lim0 = do
400nextForStream :: Buffer -> BufSize -> TBQueue Sequence -> Stream
396nextForStream :: Buffer -> BufSize -> TBQueue Sequence -> Stream
401 -> Leftover -> Bool -> BytesFilled
397 -> Leftover -> Bool -> BytesFilled
403−nextForStream _ _ _ _ _ False len = Next len CFinish
399+nextForStream _ _ _ _ _ False len = Next len Nothing
404nextForStream buf siz sq strm leftOrZero True len =
400nextForStream buf siz sq strm leftOrZero True len =
405− Next len (CNext (fillBufStream buf siz leftOrZero sq strm))
401+ Next len $ Just (fillBufStream buf siz leftOrZero sq strm)
407----------------------------------------------------------------
403----------------------------------------------------------------
@@ -417,10 +413,10 @@ fillBufFile buf siz h bytes refresh lim = do
417 return $ nextForFile len buf siz h bytes' refresh
413 return $ nextForFile len buf siz h bytes' refresh
419nextForFile :: BytesFilled -> Buffer -> BufSize -> IO.Handle -> Integer -> IO () -> Next
415nextForFile :: BytesFilled -> Buffer -> BufSize -> IO.Handle -> Integer -> IO () -> Next
420−nextForFile 0 _ _ _ _ _ = Next 0 CFinish
416+nextForFile 0 _ _ _ _ _ = Next 0 Nothing
421−nextForFile len _ _ _ 0 _ = Next len CFinish
417+nextForFile len _ _ _ 0 _ = Next len Nothing
422nextForFile len buf siz h bytes refresh =
418nextForFile len buf siz h bytes refresh =
423− Next len (CNext (fillBufFile buf siz h bytes refresh))
419+ Next len $ Just (fillBufFile buf siz h bytes refresh)
425fillBufFile :: Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> DynaNext
421fillBufFile :: Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> DynaNext
426fillBufFile buf siz fd start bytes refresh lim = do
422fillBufFile buf siz fd start bytes refresh lim = do
@@ -432,10 +428,10 @@ fillBufFile buf siz fd start bytes refresh lim = do
432 return $ nextForFile len buf siz fd (start + len') (bytes - len') refresh
428 return $ nextForFile len buf siz fd (start + len') (bytes - len') refresh
434nextForFile :: BytesFilled -> Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> Next
430nextForFile :: BytesFilled -> Buffer -> BufSize -> Fd -> Integer -> Integer -> IO () -> Next
435−nextForFile 0 _ _ _ _ _ _ = Next 0 CFinish
431+nextForFile 0 _ _ _ _ _ _ = Next 0 Nothing
436−nextForFile len _ _ _ _ 0 _ = Next len CFinish
432+nextForFile len _ _ _ _ 0 _ = Next len Nothing
437nextForFile len buf siz fd start bytes refresh =
433nextForFile len buf siz fd start bytes refresh =
438− Next len (CNext (fillBufFile buf siz fd start bytes refresh))
434+ Next len $ Just (fillBufFile buf siz fd start bytes refresh)
441mini :: Int -> Integer -> Int
437mini :: Int -> Integer -> Int