Skip to content

Commit

Permalink
After a timeout using a future, the operation that caused the timeout…
Browse files Browse the repository at this point in the history
… should be cancelled, otherwise it will still be pending. Found it investigating 58565, and could be "causing" 57799 (which would be a timeout on a read being swallowed and then disguised as a pending exception after trying to read again).

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1711303 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rmaucher committed Oct 29, 2015
1 parent 7a480dd commit 535d6cf
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions java/org/apache/tomcat/util/net/Nio2Endpoint.java
Expand Up @@ -37,6 +37,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -1151,10 +1152,11 @@ public <A> CompletionState write(ByteBuffer[] srcs, int offset, int length,
private int fillReadBuffer(boolean block) throws IOException {
socketBufferHandler.configureReadBufferForWrite();
int nRead = 0;
Future<Integer> integer = null;
if (block) {
try {
nRead = getSocket().read(socketBufferHandler.getReadBuffer()).get(
getNio2ReadTimeout(), TimeUnit.MILLISECONDS).intValue();
integer = getSocket().read(socketBufferHandler.getReadBuffer());
nRead = integer.get(getNio2ReadTimeout(), TimeUnit.MILLISECONDS).intValue();
// Blocking read so need to release here since there will
// not be a callback to a completion handler.
readPending.release();
Expand All @@ -1167,8 +1169,10 @@ private int fillReadBuffer(boolean block) throws IOException {
} catch (InterruptedException e) {
throw new IOException(e);
} catch (TimeoutException e) {
SocketTimeoutException ex = new SocketTimeoutException();
throw ex;
if (integer != null) {
integer.cancel(true);
}
throw new SocketTimeoutException();
}
} else {
Nio2Endpoint.startInline();
Expand Down Expand Up @@ -1226,11 +1230,12 @@ protected void writeNonBlocking(byte[] buf, int off, int len) throws IOException
*/
@Override
protected void doWriteInternal(boolean block) throws IOException {
Future<Integer> integer = null;
try {
socketBufferHandler.configureWriteBufferForRead();
do {
if (getSocket().write(socketBufferHandler.getWriteBuffer()).get(
getNio2WriteTimeout(), TimeUnit.MILLISECONDS).intValue() < 0) {
integer = getSocket().write(socketBufferHandler.getWriteBuffer());
if (integer.get(getNio2WriteTimeout(), TimeUnit.MILLISECONDS).intValue() < 0) {
throw new EOFException(sm.getString("iob.failedwrite"));
}
} while (socketBufferHandler.getWriteBuffer().hasRemaining());
Expand All @@ -1243,6 +1248,9 @@ protected void doWriteInternal(boolean block) throws IOException {
} catch (InterruptedException e) {
throw new IOException(e);
} catch (TimeoutException e) {
if (integer != null) {
integer.cancel(true);
}
throw new SocketTimeoutException();
}
}
Expand All @@ -1254,7 +1262,6 @@ protected void flushBlocking() throws IOException {
throw getError();
}


// Before doing a blocking flush, make sure that any pending non
// blocking write has completed.
try {
Expand Down

0 comments on commit 535d6cf

Please sign in to comment.