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/05/16 17:10:19 UTC
[tomcat] branch master updated: Handle write error when flushing
internal buffer
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 <re...@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org