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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to