Author: remm
Date: Thu Oct 29 18:19:58 2015
New Revision: 1711315
URL: http://svn.apache.org/viewvc?rev=1711315&view=rev
Log:
Cancel pending blocking IO operation following a timeout in the NIO2 connector.
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2OutputBuffer.java
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletInputStream.java
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletOutputStream.java
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
---
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java
(original)
+++
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java
Thu Oct 29 18:19:58 2015
@@ -22,6 +22,7 @@ import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -219,9 +220,10 @@ public class InternalNio2InputBuffer ext
} else {
byteBuffer.clear();
flipped = false;
+ Future<Integer> future = null;
try {
- nRead = socket.getSocket().read(byteBuffer)
- .get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
+ future = socket.getSocket().read(byteBuffer);
+ nRead = future.get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
} catch (ExecutionException e) {
if (e.getCause() instanceof IOException) {
throw (IOException) e.getCause();
@@ -231,6 +233,9 @@ public class InternalNio2InputBuffer ext
} catch (InterruptedException e) {
throw new IOException(e);
} catch (TimeoutException e) {
+ if (future != null) {
+ future.cancel(true);
+ }
throw new SocketTimeoutException();
}
if (nRead > 0) {
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2OutputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2OutputBuffer.java?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
---
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2OutputBuffer.java
(original)
+++
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2OutputBuffer.java
Thu Oct 29 18:19:58 2015
@@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -393,12 +394,14 @@ public class InternalNio2OutputBuffer ex
// Ignore timeout
}
}
+ Future<Integer> future = null;
try {
if (bufferedWrites.size() > 0) {
for (ByteBuffer buffer : bufferedWrites) {
buffer.flip();
while (buffer.hasRemaining()) {
- if
(socket.getSocket().write(buffer).get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue() < 0) {
+ future = socket.getSocket().write(buffer);
+ if (future.get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue() < 0) {
throw new
EOFException(sm.getString("iob.failedwrite"));
}
}
@@ -410,7 +413,8 @@ public class InternalNio2OutputBuffer ex
flipped = true;
}
while (byteBuffer.hasRemaining()) {
- if
(socket.getSocket().write(byteBuffer).get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue() < 0) {
+ future = socket.getSocket().write(byteBuffer);
+ if (future.get(socket.getTimeout(),
TimeUnit.MILLISECONDS).intValue() < 0) {
throw new
EOFException(sm.getString("iob.failedwrite"));
}
}
@@ -423,6 +427,9 @@ public class InternalNio2OutputBuffer ex
} catch (InterruptedException e) {
throw new IOException(e);
} catch (TimeoutException e) {
+ if (future != null) {
+ future.cancel(true);
+ }
throw new SocketTimeoutException();
}
byteBuffer.clear();
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletInputStream.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletInputStream.java?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
---
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletInputStream.java
(original)
+++
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletInputStream.java
Thu Oct 29 18:19:58 2015
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -189,9 +190,10 @@ public class Nio2ServletInputStream exte
readPending = true;
readBuffer.clear();
flipped = false;
+ Future<Integer> future = null;
try {
- nRead = channel.read(readBuffer)
- .get(wrapper.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
+ future = channel.read(readBuffer);
+ nRead = future.get(wrapper.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
readPending = false;
} catch (ExecutionException e) {
if (e.getCause() instanceof IOException) {
@@ -205,6 +207,9 @@ public class Nio2ServletInputStream exte
onError(e);
throw new IOException(e);
} catch (TimeoutException e) {
+ if (future != null) {
+ future.cancel(true);
+ }
SocketTimeoutException ex = new SocketTimeoutException();
onError(ex);
throw ex;
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletOutputStream.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletOutputStream.java?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
---
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletOutputStream.java
(original)
+++
tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/upgrade/Nio2ServletOutputStream.java
Thu Oct 29 18:19:58 2015
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -122,8 +123,10 @@ public class Nio2ServletOutputStream ext
buffer.clear();
buffer.put(b, off, len);
buffer.flip();
+ Future<Integer> future = null;
try {
- written =
channel.write(buffer).get(socketWrapper.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
+ future = channel.write(buffer);
+ written = future.get(socketWrapper.getTimeout(),
TimeUnit.MILLISECONDS).intValue();
} catch (ExecutionException e) {
if (e.getCause() instanceof IOException) {
onError(e.getCause());
@@ -136,6 +139,9 @@ public class Nio2ServletOutputStream ext
onError(e);
throw new IOException(e);
} catch (TimeoutException e) {
+ if (future != null) {
+ future.cancel(true);
+ }
SocketTimeoutException ex = new SocketTimeoutException();
onError(ex);
throw ex;
@@ -156,11 +162,13 @@ public class Nio2ServletOutputStream ext
@Override
protected void doFlush() throws IOException {
+ Future<Boolean> future = null;
try {
// Block until a possible non blocking write is done
if (writePending.tryAcquire(socketWrapper.getTimeout(),
TimeUnit.MILLISECONDS)) {
writePending.release();
- channel.flush().get(socketWrapper.getTimeout(),
TimeUnit.MILLISECONDS);
+ future = channel.flush();
+ future.get(socketWrapper.getTimeout(), TimeUnit.MILLISECONDS);
} else {
throw new TimeoutException();
}
@@ -176,6 +184,9 @@ public class Nio2ServletOutputStream ext
onError(e);
throw new IOException(e);
} catch (TimeoutException e) {
+ if (future != null) {
+ future.cancel(true);
+ }
SocketTimeoutException ex = new SocketTimeoutException();
onError(ex);
throw ex;
Modified:
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
(original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
Thu Oct 29 18:19:58 2015
@@ -495,7 +495,7 @@ public class SecureNio2Channel extends N
private class FutureRead implements Future<Integer> {
private final ByteBuffer dst;
- private final Future<Integer> integer;
+ private Future<Integer> integer;
public FutureRead(ByteBuffer dst) {
this.dst = dst;
if (netInBuffer.position() > 0) {
@@ -521,6 +521,9 @@ public class SecureNio2Channel extends N
public Integer get() throws InterruptedException, ExecutionException {
try {
return (integer == null) ? unwrap(netInBuffer.position(), -1,
TimeUnit.MILLISECONDS) : unwrap(integer.get().intValue(), -1,
TimeUnit.MILLISECONDS);
+ } catch (TimeoutException e) {
+ // Cannot happen: no timeout
+ throw new ExecutionException(e);
} finally {
readPending = false;
}
@@ -535,7 +538,7 @@ public class SecureNio2Channel extends N
readPending = false;
}
}
- private Integer unwrap(int nRead, long timeout, TimeUnit unit) throws
ExecutionException {
+ private Integer unwrap(int nRead, long timeout, TimeUnit unit) throws
ExecutionException, InterruptedException, TimeoutException {
//are we in the middle of closing or closed?
if (closing || closed)
return Integer.valueOf(-1);
@@ -567,14 +570,11 @@ public class SecureNio2Channel extends N
//if we need more network data, then bail out for now.
if (unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
if (read == 0) {
- try {
- if (timeout > 0) {
- return
unwrap(sc.read(netInBuffer).get(timeout, unit).intValue(), timeout, unit);
- } else {
- return
unwrap(sc.read(netInBuffer).get().intValue(), -1, TimeUnit.MILLISECONDS);
- }
- } catch (InterruptedException | TimeoutException
e) {
- throw new ExecutionException(e);
+ integer = sc.read(netInBuffer);
+ if (timeout > 0) {
+ return unwrap(integer.get(timeout,
unit).intValue(), timeout, unit);
+ } else {
+ return unwrap(integer.get().intValue(), -1,
TimeUnit.MILLISECONDS);
}
} else {
break;
Modified: tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml?rev=1711315&r1=1711314&r2=1711315&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml Thu Oct 29 18:19:58 2015
@@ -123,6 +123,14 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Coyote">
+ <changelog>
+ <fix>
+ Cancel pending blocking IO operation following a timeout in the NIO2
+ connector. (remm)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Cluster">
<changelog>
<fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]