diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java index e6b6c7a0c..f7de865a6 100644 --- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java +++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java @@ -188,6 +188,7 @@ public String getId() { abstract H2StreamHandler createRemotelyInitiatedStream( H2StreamChannel channel, + HttpProcessor httpProcessor, BasicHttpConnectionMetrics connMetrics, HandlerFactory pushHandlerFactory) throws IOException; @@ -211,6 +212,15 @@ private int updateWindow(final AtomicInteger window, final int delta) throws Ari } } + private int updateWindowMax(final AtomicInteger window) throws ArithmeticException { + for (;;) { + final int current = window.get(); + if (window.compareAndSet(current, Integer.MAX_VALUE)) { + return Integer.MAX_VALUE - current; + } + } + } + private int updateInputWindow( final int streamId, final AtomicInteger window, final int delta) throws ArithmeticException { final int newSize = updateWindow(window, delta); @@ -371,9 +381,9 @@ private void incrementInputCapacity( final int remainingCapacity = Integer.MAX_VALUE - streamWinSize; final int chunk = Math.min(inputCapacity, remainingCapacity); if (chunk != 0) { + updateInputWindow(streamId, inputWindow, chunk); final RawFrame windowUpdateFrame = frameFactory.createWindowUpdate(streamId, chunk); commitFrame(windowUpdateFrame); - updateInputWindow(streamId, inputWindow, chunk); } } } @@ -412,7 +422,7 @@ public final void onConnect() throws HttpException, IOException { commitFrame(settingsFrame); localSettingState = SettingsHandshake.TRANSMITTED; - maximizeConnWindow(connInputWindow.get()); + maximizeWindow(0, connInputWindow); if (streamListener != null) { final int initInputWindow = connInputWindow.get(); @@ -1024,7 +1034,7 @@ private void consumeDataFrame(final RawFrame frame, final H2Stream stream) throw } final int connWinSize = updateInputWindow(0, connInputWindow, -frameLength); if (connWinSize < CONNECTION_WINDOW_LOW_MARK) { - maximizeConnWindow(connWinSize); + maximizeWindow(0, connInputWindow); } } if (stream.isRemoteClosed()) { @@ -1039,12 +1049,11 @@ private void consumeDataFrame(final RawFrame frame, final H2Stream stream) throw stream.consumeData(payload); } - private void maximizeConnWindow(final int connWinSize) throws IOException { - final int delta = Integer.MAX_VALUE - connWinSize; + private void maximizeWindow(final int streamId, final AtomicInteger window) throws IOException { + final int delta = updateWindowMax(window); if (delta > 0) { - final RawFrame windowUpdateFrame = frameFactory.createWindowUpdate(0, delta); + final RawFrame windowUpdateFrame = frameFactory.createWindowUpdate(streamId, delta); commitFrame(windowUpdateFrame); - updateInputWindow(0, connInputWindow, delta); } }