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 680db4448d Additional fixes for 66076
680db4448d is described below

commit 680db4448d392752fb57b91639e7ab34a3f58105
Author: Mark Thomas <[email protected]>
AuthorDate: Tue May 24 17:46:20 2022 +0100

    Additional fixes for 66076
    
    The vectored IO version of the fix.
---
 java/org/apache/tomcat/util/net/AprEndpoint.java      |  7 +++++++
 java/org/apache/tomcat/util/net/Nio2Endpoint.java     |  7 +++++++
 java/org/apache/tomcat/util/net/NioEndpoint.java      | 19 ++++++++++++-------
 .../org/apache/tomcat/util/net/SocketWrapperBase.java |  4 +++-
 4 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/AprEndpoint.java 
b/java/org/apache/tomcat/util/net/AprEndpoint.java
index c02e90fc09..20d10efa11 100644
--- a/java/org/apache/tomcat/util/net/AprEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AprEndpoint.java
@@ -2813,6 +2813,13 @@ public class AprEndpoint extends 
AbstractEndpoint<Long,Long> implements SNICallB
                 return inline;
             }
 
+            @Override
+            protected boolean hasOutboundRemaining() {
+                // NIO2 never has remaining outbound data when the completion
+                // handler is called
+                return false;
+            }
+
             @Override
             public void run() {
                 // Perform the IO operation
diff --git a/java/org/apache/tomcat/util/net/Nio2Endpoint.java 
b/java/org/apache/tomcat/util/net/Nio2Endpoint.java
index 49ee411016..c5b9a395f5 100644
--- a/java/org/apache/tomcat/util/net/Nio2Endpoint.java
+++ b/java/org/apache/tomcat/util/net/Nio2Endpoint.java
@@ -1021,6 +1021,13 @@ public class Nio2Endpoint extends 
AbstractJsseEndpoint<Nio2Channel,AsynchronousS
                 return Nio2Endpoint.isInline();
             }
 
+            @Override
+            protected boolean hasOutboundRemaining() {
+                // NIO2 never has remaining outbound data when the completion
+                // handler is called
+                return false;
+            }
+
             @Override
             protected void start() {
                 if (read) {
diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java 
b/java/org/apache/tomcat/util/net/NioEndpoint.java
index b8b6d4339d..ea65dd6600 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -1622,6 +1622,11 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
                 return inline;
             }
 
+            @Override
+            protected boolean hasOutboundRemaining() {
+                return getSocket().getOutboundRemaining() > 0;
+            }
+
             @Override
             public void run() {
                 // Perform the IO operation
@@ -1654,13 +1659,13 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
                             } else {
                                 boolean doWrite = true;
                                 // Write from main buffer first
-                                if (!socketBufferHandler.isWriteBufferEmpty()) 
{
+                                if (socketOrNetworkBufferHasDataLeft()) {
                                     // There is still data inside the main 
write buffer, it needs to be written first
                                     
socketBufferHandler.configureWriteBufferForRead();
                                     do {
                                         nBytes = 
getSocket().write(socketBufferHandler.getWriteBuffer());
-                                    } while 
(!socketBufferHandler.isWriteBufferEmpty() && nBytes > 0);
-                                    if 
(!socketBufferHandler.isWriteBufferEmpty()) {
+                                    } while 
(socketOrNetworkBufferHasDataLeft() && nBytes > 0);
+                                    if (socketOrNetworkBufferHasDataLeft()) {
                                         doWrite = false;
                                     }
                                     // Preserve a negative value since it is 
an error
@@ -1681,7 +1686,8 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
                                     updateLastWrite();
                                 }
                             }
-                            if (nBytes != 0 || 
!buffersArrayHasRemaining(buffers, offset, length)) {
+                            if (nBytes != 0 || 
(!buffersArrayHasRemaining(buffers, offset, length) &&
+                                    !socketOrNetworkBufferHasDataLeft())) {
                                 completionDone = false;
                             }
                         }
@@ -1689,7 +1695,8 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
                         setError(e);
                     }
                 }
-                if (nBytes > 0 || (nBytes == 0 && 
!buffersArrayHasRemaining(buffers, offset, length))) {
+                if (nBytes > 0 || (nBytes == 0 && 
!buffersArrayHasRemaining(buffers, offset, length) &&
+                        !socketOrNetworkBufferHasDataLeft())) {
                     // The bytes processed are only updated in the completion 
handler
                     completion.completed(Long.valueOf(nBytes), this);
                 } else if (nBytes < 0 || getError() != null) {
@@ -1708,9 +1715,7 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
                     }
                 }
             }
-
         }
-
     }
 
 
diff --git a/java/org/apache/tomcat/util/net/SocketWrapperBase.java 
b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
index bcb0119fc6..d95a31a15d 100644
--- a/java/org/apache/tomcat/util/net/SocketWrapperBase.java
+++ b/java/org/apache/tomcat/util/net/SocketWrapperBase.java
@@ -1036,6 +1036,8 @@ public abstract class SocketWrapperBase<E> {
          */
         protected abstract boolean isInline();
 
+        protected abstract boolean hasOutboundRemaining();
+
         /**
          * Process the operation using the connector executor.
          * @return true if the operation was accepted, false if the executor
@@ -1087,7 +1089,7 @@ public abstract class SocketWrapperBase<E> {
                 boolean completion = true;
                 if (state.check != null) {
                     CompletionHandlerCall call = 
state.check.callHandler(currentState, state.buffers, state.offset, 
state.length);
-                    if (call == CompletionHandlerCall.CONTINUE) {
+                    if (call == CompletionHandlerCall.CONTINUE || 
state.hasOutboundRemaining()) {
                         complete = false;
                     } else if (call == CompletionHandlerCall.NONE) {
                         completion = false;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to