This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit a1ce936bcbc668c04001f924a448782105af39b8
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Mar 7 12:45:30 2024 -0500

    Improve the HTTP/2 stream prioritisation process.
    
    If a stream uses all of the connection windows and still has content to
    write, it will now be added to the backlog immediately rather than
    waiting until the write attempt for the remaining content.
    
    Addresses intermittent test failures in the HTTP/2 RFC 9218 test
---
 .../apache/coyote/http2/Http2UpgradeHandler.java   | 29 +++++++++++++++++++---
 webapps/docs/changelog.xml                         |  6 +++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index d075df3ae9..eac7b21e94 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -930,9 +930,14 @@ class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpUpgradeH
     }
 
 
+    /*
+     * Requesting an allocation from the connection window for the specified 
stream.
+     */
     int reserveWindowSize(Stream stream, int reservation, boolean block) 
throws IOException {
-        // Need to be holding the stream lock so releaseBacklog() can't notify
-        // this thread until after this thread enters wait()
+        /*
+         * Need to be holding the stream lock so releaseBacklog() can't notify 
this thread until after this thread
+         * enters wait().
+         */
         int allocation = 0;
         stream.windowAllocationLock.lock();
         try {
@@ -946,19 +951,35 @@ class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpUpgradeH
                 }
                 long windowSize = getWindowSize();
                 if (stream.getConnectionAllocationMade() > 0) {
+                    // The stream is/was in the backlog and has been granted 
an allocation - use it.
                     allocation = stream.getConnectionAllocationMade();
                     stream.setConnectionAllocationMade(0);
                 } else if (windowSize < 1) {
-                    // Has this stream been granted an allocation
-                    if (stream.getConnectionAllocationMade() == 0) {
+                    /*
+                     * The connection window has no capacity. If the stream 
has not been granted an allocation, and the
+                     * stream was not already added to the backlog due to an 
partial reservation (see next else if
+                     * block) add it to the backlog so it can obtain an 
allocation when capacity is available.
+                     */
+                    if (stream.getConnectionAllocationMade() == 0 && 
stream.getConnectionAllocationRequested() == 0) {
                         stream.setConnectionAllocationRequested(reservation);
                         backLogSize += reservation;
                         backLogStreams.add(stream);
                     }
                 } else if (windowSize < reservation) {
+                    /*
+                     * The connection window has some capacity but not enough 
to fill this reservation. Allocate what
+                     * capacity is available and add the stream to the backlog 
so it can obtain a further allocation
+                     * when capacity is available.
+                     */
                     allocation = (int) windowSize;
                     decrementWindowSize(allocation);
+                    int reservationRemaining = reservation - allocation;
+                    
stream.setConnectionAllocationRequested(reservationRemaining);
+                    backLogSize += reservationRemaining;
+                    backLogStreams.add(stream);
+
                 } else {
+                     // The connection window has sufficient capacity for this 
reservation. Allocate the full amount.
                     allocation = reservation;
                     decrementWindowSize(allocation);
                 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4ca191f54f..6aede7159f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -135,6 +135,12 @@
         <code>Context</code> to control the bahavior, defaulting to
         <code>false</code>. (remm)
       </fix>
+      <fix>
+        Improve the HTTP/2 stream prioritisation process. If a stream uses all
+        of the connection windows and still has content to write, it will now 
be
+        added to the backlog immediately rather than waiting until the write
+        attempt for the remaining content. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to