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 aabd95662ede2998934e14115c877a364c941782 Author: Mark Thomas <ma...@apache.org> AuthorDate: Fri Aug 2 10:49:25 2024 +0100 Recycle the h2 request/response as a pair rather than individually --- java/org/apache/coyote/http2/Http2Protocol.java | 46 +++++++------------------ java/org/apache/coyote/http2/Stream.java | 17 +++++---- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/java/org/apache/coyote/http2/Http2Protocol.java b/java/org/apache/coyote/http2/Http2Protocol.java index 325ee9bf10..f91e6ba796 100644 --- a/java/org/apache/coyote/http2/Http2Protocol.java +++ b/java/org/apache/coyote/http2/Http2Protocol.java @@ -110,8 +110,7 @@ public class Http2Protocol implements UpgradeProtocol { * [1] https://github.com/markt-asf/spring-boot-http2 */ private boolean discardRequestsAndResponses = false; - private final SynchronizedStack<Request> recycledRequests = new SynchronizedStack<>(); - private final SynchronizedStack<Response> recycledResponses = new SynchronizedStack<>(); + private final SynchronizedStack<Request> recycledRequestsAndResponses = new SynchronizedStack<>(); @Override public String getHttpUpgradeName(boolean isSSLEnabled) { @@ -379,8 +378,7 @@ public class Http2Protocol implements UpgradeProtocol { @Override public void setHttp11Protocol(AbstractHttp11Protocol<?> http11Protocol) { this.http11Protocol = http11Protocol; - recycledRequests.setLimit(http11Protocol.getMaxConnections()); - recycledResponses.setLimit(http11Protocol.getMaxConnections()); + recycledRequestsAndResponses.setLimit(http11Protocol.getMaxConnections()); try { ObjectName oname = this.http11Protocol.getONameForUpgrade(getUpgradeProtocolName()); @@ -418,42 +416,24 @@ public class Http2Protocol implements UpgradeProtocol { } - Request popRequest() { - Request request = null; + Request popRequestAndResponse() { + Request requestAndResponse = null; if (!discardRequestsAndResponses) { - request = recycledRequests.pop(); + requestAndResponse = recycledRequestsAndResponses.pop(); } - if (request == null) { - request = new Request(); + if (requestAndResponse == null) { + requestAndResponse = new Request(); + Response response = new Response(); + requestAndResponse.setResponse(response); } - return request; + return requestAndResponse; } - void pushRequest(Request request) { - request.recycle(); + void pushRequestAndResponse(Request requestAndResponse) { + requestAndResponse.recycle(); if (!discardRequestsAndResponses) { - recycledRequests.push(request); - } - } - - - Response popResponse() { - Response response = null; - if (!discardRequestsAndResponses) { - response = recycledResponses.pop(); - } - if (response == null) { - response = new Response(); - } - return response; - } - - - void pushResponse(Response response) { - response.recycle(); - if (!discardRequestsAndResponses) { - recycledResponses.push(response); + recycledRequestsAndResponses.push(requestAndResponse); } } } diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java index e72ce95064..9837dfd072 100644 --- a/java/org/apache/coyote/http2/Stream.java +++ b/java/org/apache/coyote/http2/Stream.java @@ -118,25 +118,24 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { super(handler.getConnectionId(), identifier); this.handler = handler; setWindowSize(handler.getRemoteSettings().getInitialWindowSize()); - Response coyoteResponse = handler.getProtocol().popResponse(); - this.coyoteResponse = coyoteResponse; - http2OutputBuffer = new Http2OutputBuffer(this.coyoteResponse, streamOutputBuffer); if (coyoteRequest == null) { // HTTP/2 new request - coyoteRequest = handler.getProtocol().popRequest(); - this.coyoteRequest = coyoteRequest; + this.coyoteRequest = handler.getProtocol().popRequestAndResponse(); + this.coyoteResponse = this.coyoteRequest.getResponse(); this.inputBuffer = new StandardStreamInputBuffer(); this.coyoteRequest.setInputBuffer(inputBuffer); } else { // HTTP/2 Push or HTTP/1.1 upgrade /* * Implementation note. The request passed in is always newly created so it is safe to recycle it for re-use - * in the Stream.recyle() method + * in the Stream.recyle() method. Need to create a matching, new response. */ this.coyoteRequest = coyoteRequest; + this.coyoteResponse = new Response(); + this.coyoteRequest.setResponse(coyoteResponse); this.inputBuffer = - new SavedRequestStreamInputBuffer((SavedRequestInputFilter) coyoteRequest.getInputBuffer()); + new SavedRequestStreamInputBuffer((SavedRequestInputFilter) this.coyoteRequest.getInputBuffer()); // Headers have been read by this point state.receivedStartOfHeaders(); if (HTTP_UPGRADE_STREAM.equals(identifier)) { @@ -156,6 +155,7 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { state.receivedEndOfStream(); } this.coyoteRequest.setSendfile(handler.hasAsyncIO() && handler.getProtocol().getUseSendfile()); + http2OutputBuffer = new Http2OutputBuffer(this.coyoteResponse, streamOutputBuffer); this.coyoteResponse.setOutputBuffer(http2OutputBuffer); this.coyoteRequest.setResponse(coyoteResponse); this.coyoteRequest.protocol().setString("HTTP/2.0"); @@ -807,9 +807,8 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { } handler.replaceStream(this, new RecycledStream(getConnectionId(), getIdentifier(), state, remaining)); coyoteRequest.recycle(); - handler.getProtocol().pushRequest(coyoteRequest); coyoteResponse.recycle(); - handler.getProtocol().pushResponse(coyoteResponse); + handler.getProtocol().pushRequestAndResponse(coyoteRequest); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org