This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new b099135b71 Add API callback to allow avoiding recycling processors
b099135b71 is described below
commit b099135b716313973280306352271f00dbfa6bf6
Author: remm <[email protected]>
AuthorDate: Wed Nov 11 09:12:07 2026 +0100
Add API callback to allow avoiding recycling processors
Same reason for HTTP/3 as for HTTP/2 (which is an upgrade protocol, so
it does it without the API).
---
java/org/apache/coyote/AbstractProtocol.java | 13 ++++++++++++-
java/org/apache/coyote/Processor.java | 13 +++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/coyote/AbstractProtocol.java
b/java/org/apache/coyote/AbstractProtocol.java
index 87b8193d76..8e83bb43a9 100644
--- a/java/org/apache/coyote/AbstractProtocol.java
+++ b/java/org/apache/coyote/AbstractProtocol.java
@@ -1673,7 +1673,11 @@ public abstract class AbstractProtocol<S> implements
ProtocolHandler, MBeanRegis
}
/**
- * Pushes a processor to the pool.
+ * Pushes a processor to the pool. A processor that is not reusable is
+ * not added to the pool and is unregistered instead. This may happen,
+ * for example, after an asynchronous timeout or error while an
+ * application thread was blocked in a write. Reusing such a processor
+ * could write stale data to another request.
*
* @param processor The processor
*
@@ -1682,6 +1686,13 @@ public abstract class AbstractProtocol<S> implements
ProtocolHandler, MBeanRegis
@SuppressWarnings("sync-override") // Size may exceed cache size a bit
@Override
public boolean push(Processor processor) {
+ if (!processor.isReusable()) {
+ // Also make sure any waiting-processor registration is
+ // removed before the processor is unregistered.
+ handler.getProtocol().removeWaitingProcessor(processor);
+ handler.unregister(processor);
+ return false;
+ }
int cacheSize = handler.getProtocol().getProcessorCache();
boolean offer = cacheSize == -1 || size.get() < cacheSize;
// avoid over growing our cache or add after we have stopped
diff --git a/java/org/apache/coyote/Processor.java
b/java/org/apache/coyote/Processor.java
index e5f82f09e2..d7f816afb4 100644
--- a/java/org/apache/coyote/Processor.java
+++ b/java/org/apache/coyote/Processor.java
@@ -89,6 +89,19 @@ public interface Processor {
*/
void recycle();
+ /**
+ * Whether this processor may be returned to the shared processor pool
+ * after {@link #recycle()}. A processor must not be reused if a
+ * non-container thread may still be using its request, response or
+ * output state (for example after an asynchronous timeout or error
+ * while an application thread was blocked in a write).
+ *
+ * @return {@code true} if the processor may be pooled for reuse
+ */
+ default boolean isReusable() {
+ return true;
+ }
+
/**
* Set the SSL information for this HTTP connection.
*
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]