This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new a49ee3d Handle write error when flushing internal buffer a49ee3d is described below commit a49ee3debf58774e0ca4f738bb72953c57ce522e Author: remm <r...@apache.org> AuthorDate: Thu May 16 19:10:03 2019 +0200 Handle write error when flushing internal buffer Checking for a negative result wasn't done, so do that now for NIO and NIO2. Fix outdated comments for cut & paste. Remove read sync for NIO2, it's most likely not useful. --- java/org/apache/tomcat/util/net/Nio2Endpoint.java | 41 ++++++++++++++--------- java/org/apache/tomcat/util/net/NioEndpoint.java | 9 +++-- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/java/org/apache/tomcat/util/net/Nio2Endpoint.java b/java/org/apache/tomcat/util/net/Nio2Endpoint.java index c5a3328..748c929 100644 --- a/java/org/apache/tomcat/util/net/Nio2Endpoint.java +++ b/java/org/apache/tomcat/util/net/Nio2Endpoint.java @@ -1011,18 +1011,24 @@ public class Nio2Endpoint extends AbstractJsseEndpoint<Nio2Channel,AsynchronousS } @Override + protected void end() { + // Restore regular notifications + if (read) { + readNotify = false; + } else { + writeNotify = false; + } + } + + @Override public void run() { if (read) { long nBytes = 0; - // Read from main buffer first + // If there is still data inside the main read buffer, it needs to be read first if (!socketBufferHandler.isReadBufferEmpty()) { - // There is still data inside the main read buffer, it needs to be read first - synchronized (readCompletionHandler) { - // Note: It is not necessary to put this code in the completion handler - socketBufferHandler.configureReadBufferForRead(); - for (int i = 0; i < length && !socketBufferHandler.isReadBufferEmpty(); i++) { - nBytes += transfer(socketBufferHandler.getReadBuffer(), buffers[offset + i]); - } + socketBufferHandler.configureReadBufferForRead(); + for (int i = 0; i < length && !socketBufferHandler.isReadBufferEmpty(); i++) { + nBytes += transfer(socketBufferHandler.getReadBuffer(), buffers[offset + i]); } if (nBytes > 0) { completion.completed(Long.valueOf(nBytes), this); @@ -1032,24 +1038,27 @@ public class Nio2Endpoint extends AbstractJsseEndpoint<Nio2Channel,AsynchronousS getSocket().read(buffers, offset, length, timeout, unit, this, completion); } } else { - // Write from main buffer first + // If there is still data inside the main write buffer, it needs to be written first if (!socketBufferHandler.isWriteBufferEmpty()) { - // There is still data inside the main write buffer, it needs to be written first socketBufferHandler.configureWriteBufferForRead(); getSocket().write(socketBufferHandler.getWriteBuffer(), null, new CompletionHandler<Integer, Void>() { @Override - public void completed(Integer result, Void attachment) { - run(); + public void completed(Integer nBytes, Void attachment) { + if (nBytes.intValue() < 0) { + failed(new EOFException(), null); + } else { + // Continue until everything is written + run(); + } } @Override public void failed(Throwable exc, Void attachment) { - handler.failed(exc, Nio2OperationState.this.attachment); + completion.failed(exc, Nio2OperationState.this); } }); - return; + } else { + getSocket().write(buffers, offset, length, timeout, unit, this, completion); } - // It should be less necessary to check the buffer state as it is easy to flush before - getSocket().write(buffers, offset, length, timeout, unit, this, completion); } } } diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java index b3f1f2f..6b7a9fa 100644 --- a/java/org/apache/tomcat/util/net/NioEndpoint.java +++ b/java/org/apache/tomcat/util/net/NioEndpoint.java @@ -1456,11 +1456,16 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel> if (!socketBufferHandler.isWriteBufferEmpty()) { // There is still data inside the main write buffer, it needs to be written first socketBufferHandler.configureWriteBufferForRead(); - getSocket().write(socketBufferHandler.getWriteBuffer()); - // Start operation only if the main write buffer is now empty + do { + nBytes = getSocket().write(socketBufferHandler.getWriteBuffer()); + } while (!socketBufferHandler.isWriteBufferEmpty() && nBytes > 0); if (!socketBufferHandler.isWriteBufferEmpty()) { doWrite = false; } + // Preserve a negative value since it is an error + if (nBytes > 0) { + nBytes = 0; + } } if (doWrite) { nBytes = getSocket().write(buffers, offset, length); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org