This is an automated email from the ASF dual-hosted git repository.
markt-asf 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 b28ea3a22a Handle concurrent completion and timeout
b28ea3a22a is described below
commit b28ea3a22ace9050120408998982e980c725b9b7
Author: Mark Thomas <[email protected]>
AuthorDate: Sat Nov 7 20:58:31 2026 +0000
Handle concurrent completion and timeout
Co-authored by: Claude / Sonnet 5.5
---
.../apache/tomcat/util/net/SocketWrapperBase.java | 36 +++++++++++++++++++---
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
index 5540cd77f2..71e600fcf6 100644
--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
+++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
@@ -1767,14 +1767,22 @@ public abstract class SocketWrapperBase<E> {
timeoutMillis = (timeoutExpiry -
System.nanoTime()) / 1_000_000;
}
if (state.state == CompletionState.PENDING) {
- if (handler != null &&
state.callHandler.compareAndSet(true, false)) {
- handler.failed(new
SocketTimeoutException(getTimeoutMsg(read)), attachment);
+ if (handler != null) {
+ if (state.callHandler.compareAndSet(true,
false)) {
+ handler.failed(new
SocketTimeoutException(getTimeoutMsg(read)), attachment);
+ } else {
+ awaitHandlerCompletion(state);
+ }
}
return CompletionState.ERROR;
}
} catch (InterruptedException e) {
- if (handler != null &&
state.callHandler.compareAndSet(true, false)) {
- handler.failed(new
SocketTimeoutException(getTimeoutMsg(read)), attachment);
+ if (handler != null) {
+ if (state.callHandler.compareAndSet(true, false)) {
+ handler.failed(new
SocketTimeoutException(getTimeoutMsg(read)), attachment);
+ } else {
+ awaitHandlerCompletion(state);
+ }
}
return CompletionState.ERROR;
}
@@ -1785,6 +1793,26 @@ public abstract class SocketWrapperBase<E> {
}
+ /**
+ * The completion thread has claimed the right to call the handler but has
not yet finished doing so. Wait for it to
+ * finish (it updates the state and notifies once the handler has
returned) so that the caller does not return
+ * before the handler has been called. The caller must hold the monitor
for the state.
+ */
+ private void awaitHandlerCompletion(OperationState<?> state) {
+ boolean interrupted = false;
+ while (state.state == CompletionState.PENDING) {
+ try {
+ state.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+
private String getTimeoutMsg(boolean read) {
if (read) {
return sm.getString("socketWrapper.readTimeout");
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]