This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new e5cb2c9e4d Handle spurious wake-ups while waiting for an allocation e5cb2c9e4d is described below commit e5cb2c9e4d6690d09445f344ae1515a95f7b9eb1 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Jul 6 14:05:48 2023 +0100 Handle spurious wake-ups while waiting for an allocation --- .../coyote/http2/WindowAllocationManager.java | 34 +++++++++++++++++----- webapps/docs/changelog.xml | 4 +++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/java/org/apache/coyote/http2/WindowAllocationManager.java b/java/org/apache/coyote/http2/WindowAllocationManager.java index 94558b15b1..e784c4083c 100644 --- a/java/org/apache/coyote/http2/WindowAllocationManager.java +++ b/java/org/apache/coyote/http2/WindowAllocationManager.java @@ -16,6 +16,8 @@ */ package org.apache.coyote.http2; +import java.util.concurrent.TimeUnit; + import org.apache.coyote.ActionCode; import org.apache.coyote.Response; import org.apache.juli.logging.Log; @@ -133,7 +135,7 @@ class WindowAllocationManager { } - private void waitFor(int waitTarget, long timeout) throws InterruptedException { + private void waitFor(int waitTarget, final long timeout) throws InterruptedException { synchronized (stream) { if (waitingFor != NONE) { throw new IllegalStateException(sm.getString("windowAllocationManager.waitFor.ise", @@ -141,12 +143,30 @@ class WindowAllocationManager { } waitingFor = waitTarget; - - if (timeout < 0) { - stream.wait(); - } else { - stream.wait(timeout); - } + long startNanos = -1; + + // Loop to handle spurious wake-ups + do { + if (timeout < 0) { + stream.wait(); + } else { + long timeoutRemaining; + if (startNanos == -1) { + startNanos = System.nanoTime(); + timeoutRemaining = timeout; + } else { + long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos); + if (elapsedMillis == 0) { + elapsedMillis = 1; + } + timeoutRemaining = timeout - elapsedMillis; + if (timeoutRemaining <= 0) { + return; + } + } + stream.wait(timeoutRemaining); + } + } while (waitingFor != NONE); } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index cbc85b9147..562e76c4be 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -124,6 +124,10 @@ code paths that could allow a notification from the Poller to be missed resuting in a timeout rather than the expected read or write. (markt) </fix> + <fix> + Refactor waiting for an HTTP/2 stream or connection window update to + handle spurious wake-ups during the wait. (markt) + </fix> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org