on master help sign in
Guarantee atomicity of WINDOW_UPDATE increments.
2b97428Lucas DiCioccio
warp/Network/Wai/Handler/Warp/HTTP2/Receiver.hs+10−4
@@ -232,9 +232,12 @@ control FrameGoAway _ _ Context{controlQ} = do
232
232
233control FrameWindowUpdate header bs Context{connectionWindow} = do
233control FrameWindowUpdate header bs Context{connectionWindow} = do
234 WindowUpdateFrame n <- guardIt $ decodeWindowUpdateFrame header bs
234 WindowUpdateFrame n <- guardIt $ decodeWindowUpdateFrame header bs
235+ !w <- atomically $ do
235− !w <- (n +) <$> atomically (readTVar connectionWindow)
236+ w0 <- readTVar connectionWindow
237+ let w1 = w0 + n
238+ writeTVar connectionWindow w1
239+ return w1
236 when (isWindowOverflow w) $ E.throwIO $ ConnectionError FlowControlError "control window should be less than 2^31"
240 when (isWindowOverflow w) $ E.throwIO $ ConnectionError FlowControlError "control window should be less than 2^31"
237− atomically $ writeTVar connectionWindow w
238 return True
241 return True
239
242
240control _ _ _ _ =
243control _ _ _ _ =
@@ -336,10 +339,13 @@ stream FrameContinuation FrameHeader{flags} frag ctx (Open (Continued rfrags siz
336
339
337stream FrameWindowUpdate header@FrameHeader{streamId} bs _ s Stream{streamWindow} = do
340stream FrameWindowUpdate header@FrameHeader{streamId} bs _ s Stream{streamWindow} = do
338 WindowUpdateFrame n <- guardIt $ decodeWindowUpdateFrame header bs
341 WindowUpdateFrame n <- guardIt $ decodeWindowUpdateFrame header bs
342+ !w <- atomically $ do
339− !w <- (n +) <$> atomically (readTVar streamWindow)
343+ w0 <- readTVar streamWindow
344+ let w1 = w0 + n
345+ writeTVar streamWindow w1
346+ return w1
340 when (isWindowOverflow w) $
347 when (isWindowOverflow w) $
341 E.throwIO $ StreamError FlowControlError streamId
348 E.throwIO $ StreamError FlowControlError streamId
342− atomically $ writeTVar streamWindow w
343 return s
349 return s
344
350
345stream FrameRSTStream header bs ctx _ strm = do
351stream FrameRSTStream header bs ctx _ strm = do