You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2019/12/04 14:01:23 UTC

[tomcat] branch 8.5.x updated (1a12467 -> 17c3094)

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

remm pushed a change to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git.


    from 1a12467  Fix a couple of very unlikely concurrency issues writing WebSocket msgs
     new dee4413  Call completion handler directly on timeout
     new 17c3094  Fix merge

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 java/org/apache/tomcat/util/net/SocketWrapperBase.java | 14 +++++++++++---
 webapps/docs/changelog.xml                             |  5 +++++
 2 files changed, 16 insertions(+), 3 deletions(-)


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


[tomcat] 01/02: Call completion handler directly on timeout

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit dee4413449fc2070a220cd66a2f0d05c7c81cd43
Author: remm <re...@apache.org>
AuthorDate: Wed Dec 4 14:42:34 2019 +0100

    Call completion handler directly on timeout
    
    Although it is possible I will redo it in a more precise way (but it is
    harder) so that if an operation requires multiple IO operations it does
    use decreasing timeouts, for now simply call the completion handler
    directly on timeout to enforce the "global" operation timeout. The
    actual IO will remain pending until it completes on its own, taking at
    most the duration of the timeout in addition to the operation timeout.
---
 java/org/apache/tomcat/util/net/SocketWrapperBase.java | 13 ++++++++++---
 webapps/docs/changelog.xml                             |  5 +++++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
index 0d348a6..d1127ed 100644
--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
+++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
@@ -910,6 +910,7 @@ public abstract class SocketWrapperBase<E> {
         protected final CompletionHandler<Long, ? super A> handler;
         protected final Semaphore semaphore;
         protected final VectoredIOCompletionHandler<A> completion;
+        protected final AtomicBoolean callHandler;
         protected OperationState(boolean read, ByteBuffer[] buffers, int offset, int length,
                 BlockingMode block, long timeout, TimeUnit unit, A attachment,
                 CompletionCheck check, CompletionHandler<Long, ? super A> handler,
@@ -926,6 +927,7 @@ public abstract class SocketWrapperBase<E> {
             this.handler = handler;
             this.semaphore = semaphore;
             this.completion = completion;
+            callHandler = (handler != null) ? new AtomicBoolean(true) : null;
         }
         protected volatile long nBytes = 0;
         protected volatile CompletionState state = CompletionState.PENDING;
@@ -1008,7 +1010,7 @@ public abstract class SocketWrapperBase<E> {
                         state.state = currentState;
                     }
                     state.end();
-                    if (completion && state.handler != null) {
+                    if (completion && state.handler != null && state.callHandler.compareAndSet(true, false)) {
                         state.handler.completed(Long.valueOf(state.nBytes), state.attachment);
                     }
                     synchronized (state) {
@@ -1049,7 +1051,7 @@ public abstract class SocketWrapperBase<E> {
                 state.state = state.isInline() ? CompletionState.ERROR : CompletionState.DONE;
             }
             state.end();
-            if (state.handler != null) {
+            if (state.handler != null && state.callHandler.compareAndSet(true, false)) {
                 state.handler.failed(exc, state.attachment);
             }
             synchronized (state) {
@@ -1379,10 +1381,15 @@ public abstract class SocketWrapperBase<E> {
                     try {
                         state.wait(unit.toMillis(timeout));
                         if (state.state == CompletionState.PENDING) {
+                            if (handler != null && state.callHandler.compareAndSet(true, false)) {
+                                handler.failed(new SocketTimeoutException(), attachment);
+                            }
                             return CompletionState.ERROR;
                         }
                     } catch (InterruptedException e) {
-                        completion.failed(new SocketTimeoutException(), state);
+                        if (handler != null && state.callHandler.compareAndSet(true, false)) {
+                            handler.failed(new SocketTimeoutException(), attachment);
+                        }
                         return CompletionState.ERROR;
                     }
                 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 572808d..7976830 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -117,6 +117,11 @@
         All regular writes will now be buffered for a more predictable
         behavior. (remm)
       </fix>
+      <fix>
+        Send an exception directly to the completion handler when a timeout
+        exception occurs for the operation, and add a boolean to make sure the
+        completion handler is called only once. (remm/markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="WebSocket">


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


[tomcat] 02/02: Fix merge

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 17c3094a45bab53b2267d8ed137c6c3750c7fc6c
Author: remm <re...@apache.org>
AuthorDate: Wed Dec 4 15:00:59 2019 +0100

    Fix merge
---
 java/org/apache/tomcat/util/net/SocketWrapperBase.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
index d1127ed..adeba23 100644
--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
+++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
@@ -28,6 +28,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;


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