You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/01/29 20:11:48 UTC

svn commit: r1655807 - in /tomcat/trunk/java/org/apache: coyote/ajp/ coyote/http11/ coyote/http11/upgrade/ tomcat/util/net/

Author: markt
Date: Thu Jan 29 19:11:47 2015
New Revision: 1655807

URL: http://svn.apache.org/r1655807
Log:
First pass at cleaning up timeouts.

Modified:
    tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java
    tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Thu Jan 29 19:11:47 2015
@@ -683,7 +683,7 @@ public class AjpProcessor<S> extends Abs
         } else {
             // Set keep alive timeout for next request if enabled
             if (keepAliveTimeout > 0) {
-                socketWrapper.setTimeout(keepAliveTimeout);
+                socketWrapper.setReadTimeout(keepAliveTimeout);
             }
             request.updateCounters();
             if (getErrorState().isError()) {
@@ -724,7 +724,7 @@ public class AjpProcessor<S> extends Abs
                 }
                 // Set back timeout if keep alive timeout is enabled
                 if (keepAliveTimeout > 0) {
-                    socketWrapper.setTimeout(soTimeout);
+                    socketWrapper.setReadTimeout(soTimeout);
                 }
                 // Check message type, process right away and break if
                 // not regular request processing
@@ -830,7 +830,7 @@ public class AjpProcessor<S> extends Abs
             rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
             // Set keep alive timeout for next request if enabled
             if (keepAliveTimeout > 0) {
-                socketWrapper.setTimeout(keepAliveTimeout);
+                socketWrapper.setReadTimeout(keepAliveTimeout);
             }
 
             recycle();
@@ -1534,9 +1534,6 @@ public class AjpProcessor<S> extends Abs
 
 
     private void writeData(ByteChunk chunk) throws IOException {
-        // Prevent timeout
-        socketWrapper.access();
-
         boolean blocking = (response.getWriteListener() == null);
 
         int len = chunk.getLength();

Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Thu Jan 29 19:11:47 2015
@@ -945,12 +945,6 @@ public abstract class AbstractHttp11Proc
 
 
     /**
-     * Set the socket timeout.
-     */
-    protected abstract void setSocketTimeout(int timeout) throws IOException;
-
-
-    /**
      * Process pipelined HTTP requests using the specified input and output
      * streams.
      *
@@ -1004,7 +998,7 @@ public abstract class AbstractHttp11Proc
                         break;
                     }
                     if (!disableUploadTimeout) {
-                        setSocketTimeout(connectionUploadTimeout);
+                        socketWrapper.setReadTimeout(connectionUploadTimeout);
                     }
                 }
             } catch (IOException e) {
@@ -1140,9 +1134,9 @@ public abstract class AbstractHttp11Proc
             if (!disableUploadTimeout) {
                 int soTimeout = endpoint.getSoTimeout();
                 if(soTimeout > 0) {
-                    setSocketTimeout(soTimeout);
+                    socketWrapper.setReadTimeout(soTimeout);
                 } else {
-                    setSocketTimeout(0);
+                    socketWrapper.setReadTimeout(0);
                 }
             }
 
@@ -1188,7 +1182,7 @@ public abstract class AbstractHttp11Proc
             if (keptAlive) {
                 // Haven't read the request line and have previously processed a
                 // request. Must be keep-alive. Make sure poller uses keepAlive.
-                socketWrapper.setTimeout(endpoint.getKeepAliveTimeout());
+                socketWrapper.setReadTimeout(endpoint.getKeepAliveTimeout());
             }
         } else {
             // Started to read request line.
@@ -1205,7 +1199,7 @@ public abstract class AbstractHttp11Proc
                 // Need to keep processor associated with socket
                 readComplete = false;
                 // Make sure poller uses soTimeout from here onwards
-                socketWrapper.setTimeout(endpoint.getSoTimeout());
+                socketWrapper.setReadTimeout(endpoint.getSoTimeout());
             }
         }
         return true;

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Thu Jan 29 19:11:47 2015
@@ -75,12 +75,6 @@ public class Http11AprProcessor extends
     // --------------------------------------------------------- Public Methods
 
     @Override
-    protected void setSocketTimeout(int timeout) {
-        Socket.timeoutSet(socketWrapper.getSocket().longValue(), timeout * 1000);
-    }
-
-
-    @Override
     protected void resetTimeouts() {
         // NO-OP for APR
     }
@@ -91,8 +85,8 @@ public class Http11AprProcessor extends
         // NOOP for APR
     }
 
-    // ----------------------------------------------------- ActionHook Methods
 
+    // ----------------------------------------------------- ActionHook Methods
 
     /**
      * Send an action to the connector.

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java Thu Jan 29 19:11:47 2015
@@ -82,20 +82,14 @@ public class Http11Nio2Processor extends
 
             // Reset the timeout
             if (keepAlive) {
-                socketWrapper.setTimeout(endpoint.getKeepAliveTimeout());
+                socketWrapper.setReadTimeout(endpoint.getKeepAliveTimeout());
             } else {
-                socketWrapper.setTimeout(endpoint.getSoTimeout());
+                socketWrapper.setReadTimeout(endpoint.getSoTimeout());
             }
         }
     }
 
 
-    @Override
-    protected void setSocketTimeout(int timeout) throws IOException {
-        socketWrapper.setTimeout(timeout);
-    }
-
-
     // ----------------------------------------------------- ActionHook Methods
 
     /**

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Thu Jan 29 19:11:47 2015
@@ -64,26 +64,21 @@ public class Http11NioProcessor extends
 
     @Override
     protected void resetTimeouts() {
-        final NioEndpoint.NioSocketWrapper attach = (NioEndpoint.NioSocketWrapper)socketWrapper.getSocket().getAttachment();
+        final NioEndpoint.NioSocketWrapper attach =
+                (NioEndpoint.NioSocketWrapper)socketWrapper.getSocket().getAttachment();
         if (!getErrorState().isError() && attach != null &&
                 asyncStateMachine.isAsyncDispatching()) {
 
             // Reset the timeout
             if (keepAlive) {
-                attach.setTimeout(endpoint.getKeepAliveTimeout());
+                attach.setReadTimeout(endpoint.getKeepAliveTimeout());
             } else {
-                attach.setTimeout(endpoint.getSoTimeout());
+                attach.setReadTimeout(endpoint.getSoTimeout());
             }
         }
     }
 
 
-    @Override
-    protected void setSocketTimeout(int timeout) throws IOException {
-        socketWrapper.getSocket().getIOChannel().socket().setSoTimeout(timeout);
-    }
-
-
     // ----------------------------------------------------- ActionHook Methods
 
     /**

Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java Thu Jan 29 19:11:47 2015
@@ -54,7 +54,7 @@ public class UpgradeProcessor<S> impleme
         this.upgradeServletOutputStream = new UpgradeServletOutputStream(wrapper);
 
         wrapper.unRead(leftOverInput);
-        wrapper.setTimeout(INFINITE_TIMEOUT);
+        wrapper.setReadTimeout(INFINITE_TIMEOUT);
     }
 
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Thu Jan 29 19:11:47 2015
@@ -2391,16 +2391,6 @@ public class AprEndpoint extends Abstrac
         }
 
 
-        // TODO Can this be removed once all reads and writes are handled within
-        // this class?
-        @Override
-        public void setTimeout(long timeout) {
-            super.setTimeout(timeout);
-            Socket.timeoutSet(getSocket().longValue(), timeout * 1000);
-        }
-
-
-
         @Override
         public int read(boolean block, byte[] b, int off, int len) throws IOException {
 
@@ -2429,6 +2419,9 @@ public class AprEndpoint extends Abstrac
             readLock.lock();
             try {
                 if (getBlockingStatus() == block) {
+                    if (block) {
+                        Socket.timeoutSet(getSocket().longValue(), getReadTimeout() * 1000);
+                    }
                     result = Socket.recv(getSocket().longValue(), b, off, len);
                     readDone = true;
                 }
@@ -2439,9 +2432,13 @@ public class AprEndpoint extends Abstrac
             if (!readDone) {
                 writeLock.lock();
                 try {
-                    setBlockingStatus(block);
                     // Set the current settings for this socket
-                    Socket.optSet(getSocket().longValue(), Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
+                    setBlockingStatus(block);
+                    if (block) {
+                        Socket.timeoutSet(getSocket().longValue(), getReadTimeout() * 1000);
+                    } else {
+                        Socket.timeoutSet(getSocket().longValue(), 0);
+                    }
                     // Downgrade the lock
                     readLock.lock();
                     try {
@@ -2525,7 +2522,7 @@ public class AprEndpoint extends Abstrac
 
 
         @Override
-        protected void doWrite(boolean block) throws IOException {
+        protected void doWriteInternal(boolean block) throws IOException {
             if (closed) {
                 throw new IOException(sm.getString("apr.closed", getSocket()));
             }
@@ -2536,6 +2533,9 @@ public class AprEndpoint extends Abstrac
             readLock.lock();
             try {
                 if (getBlockingStatus() == block) {
+                    if (block) {
+                        Socket.timeoutSet(getSocket().longValue(), getWriteTimeout() * 1000);
+                    }
                     doWriteInternal();
                 }
             } finally {
@@ -2547,7 +2547,7 @@ public class AprEndpoint extends Abstrac
                 // Set the current settings for this socket
                 setBlockingStatus(block);
                 if (block) {
-                    Socket.timeoutSet(getSocket().longValue(), getEndpoint().getSoTimeout() * 1000);
+                    Socket.timeoutSet(getSocket().longValue(), getWriteTimeout() * 1000);
                 } else {
                     Socket.timeoutSet(getSocket().longValue(), 0);
                 }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Thu Jan 29 19:11:47 2015
@@ -814,13 +814,14 @@ public class Nio2Endpoint extends Abstra
                             Nio2SocketWrapper.this.bufferedWrites.clear();
                             ByteBuffer[] array = arrayList.toArray(new ByteBuffer[arrayList.size()]);
                             Nio2SocketWrapper.this.getSocket().write(array, 0, array.length,
-                                    Nio2SocketWrapper.this.getTimeout(), TimeUnit.MILLISECONDS,
+                                    Nio2SocketWrapper.this.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
                                     array, gatheringWriteCompletionHandler);
                             nestedWriteCompletionCount.get().decrementAndGet();
                         } else if (attachment.hasRemaining()) {
                             // Regular write
                             nestedWriteCompletionCount.get().incrementAndGet();
-                            Nio2SocketWrapper.this.getSocket().write(attachment, Nio2SocketWrapper.this.getTimeout(),
+                            Nio2SocketWrapper.this.getSocket().write(attachment,
+                                    Nio2SocketWrapper.this.getNio2WriteTimeout(),
                                     TimeUnit.MILLISECONDS, attachment, writeCompletionHandler);
                             nestedWriteCompletionCount.get().decrementAndGet();
                         } else {
@@ -874,7 +875,7 @@ public class Nio2Endpoint extends Abstra
                             Nio2SocketWrapper.this.bufferedWrites.clear();
                             ByteBuffer[] array = arrayList.toArray(new ByteBuffer[arrayList.size()]);
                             Nio2SocketWrapper.this.getSocket().write(array, 0, array.length,
-                                    Nio2SocketWrapper.this.getTimeout(), TimeUnit.MILLISECONDS,
+                                    Nio2SocketWrapper.this.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
                                     array, gatheringWriteCompletionHandler);
                             nestedWriteCompletionCount.get().decrementAndGet();
                         } else {
@@ -934,12 +935,6 @@ public class Nio2Endpoint extends Abstra
         }
 
         @Override
-        public long getTimeout() {
-            long timeout = super.getTimeout();
-            return (timeout > 0) ? timeout : Long.MAX_VALUE;
-        }
-
-        @Override
         public void setUpgraded(boolean upgraded) {
             if (upgraded && !isUpgraded()) {
                 upgradeInit = true;
@@ -1090,7 +1085,7 @@ public class Nio2Endpoint extends Abstra
             if (block) {
                 try {
                     nRead = getSocket().read(socketBufferHandler.getReadBuffer()).get(
-                            getTimeout(), TimeUnit.MILLISECONDS).intValue();
+                            getNio2ReadTimeout(), TimeUnit.MILLISECONDS).intValue();
                     readPending.release();
                 } catch (ExecutionException e) {
                     if (e.getCause() instanceof IOException) {
@@ -1106,8 +1101,8 @@ public class Nio2Endpoint extends Abstra
                 }
             } else {
                 Nio2Endpoint.startInline();
-                getSocket().read(socketBufferHandler.getReadBuffer(), getTimeout(), TimeUnit.MILLISECONDS,
-                        this, readCompletionHandler);
+                getSocket().read(socketBufferHandler.getReadBuffer(), getNio2ReadTimeout(),
+                        TimeUnit.MILLISECONDS, this, readCompletionHandler);
                 Nio2Endpoint.endInline();
                 if (readPending.availablePermits() == 1) {
                     nRead = socketBufferHandler.getReadBuffer().position();
@@ -1159,12 +1154,12 @@ public class Nio2Endpoint extends Abstra
          *              blocking case
          */
         @Override
-        protected void doWrite(boolean block) throws IOException {
+        protected void doWriteInternal(boolean block) throws IOException {
             try {
                 socketBufferHandler.configureWriteBufferForRead();
                 do {
-                    if (getSocket().write(socketBufferHandler.getWriteBuffer()).get(getTimeout(),
-                            TimeUnit.MILLISECONDS).intValue() < 0) {
+                    if (getSocket().write(socketBufferHandler.getWriteBuffer()).get(
+                            getNio2WriteTimeout(), TimeUnit.MILLISECONDS).intValue() < 0) {
                         throw new EOFException(sm.getString("iob.failedwrite"));
                     }
                 } while (socketBufferHandler.getWriteBuffer().hasRemaining());
@@ -1187,7 +1182,7 @@ public class Nio2Endpoint extends Abstra
             // Before doing a blocking flush, make sure that any pending non
             // blocking write has completed.
             try {
-                if (writePending.tryAcquire(getTimeout(), TimeUnit.MILLISECONDS)) {
+                if (writePending.tryAcquire(getNio2WriteTimeout(), TimeUnit.MILLISECONDS)) {
                     writePending.release();
                 } else {
                     throw new SocketTimeoutException();
@@ -1221,13 +1216,13 @@ public class Nio2Endpoint extends Abstra
                         bufferedWrites.clear();
                         ByteBuffer[] array = arrayList.toArray(new ByteBuffer[arrayList.size()]);
                         Nio2Endpoint.startInline();
-                        getSocket().write(array, 0, array.length, getTimeout(),
+                        getSocket().write(array, 0, array.length, getNio2WriteTimeout(),
                                 TimeUnit.MILLISECONDS, array, gatheringWriteCompletionHandler);
                         Nio2Endpoint.endInline();
                     } else if (socketBufferHandler.getWriteBuffer().hasRemaining()) {
                         // Regular write
                         Nio2Endpoint.startInline();
-                        getSocket().write(socketBufferHandler.getWriteBuffer(), getTimeout(),
+                        getSocket().write(socketBufferHandler.getWriteBuffer(), getNio2WriteTimeout(),
                                 TimeUnit.MILLISECONDS, socketBufferHandler.getWriteBuffer(),
                                 writeCompletionHandler);
                         Nio2Endpoint.endInline();
@@ -1294,7 +1289,7 @@ public class Nio2Endpoint extends Abstra
                 getSocket().getBufHandler().configureReadBufferForWrite();
                 Nio2Endpoint.startInline();
                 getSocket().read(getSocket().getBufHandler().getReadBuffer(),
-                        getTimeout(), TimeUnit.MILLISECONDS, this, awaitBytesHandler);
+                        getNio2ReadTimeout(), TimeUnit.MILLISECONDS, this, awaitBytesHandler);
                 Nio2Endpoint.endInline();
             }
         }
@@ -1313,6 +1308,26 @@ public class Nio2Endpoint extends Abstra
         }
 
 
+        private long getNio2ReadTimeout() {
+            long readTimeout = getReadTimeout();
+            if (readTimeout > 0) {
+                return readTimeout;
+            }
+            // NIO2 can't do infinite timeout so use Long.MAX_VALUE
+            return Long.MAX_VALUE;
+        }
+
+
+        private long getNio2WriteTimeout() {
+            long writeTimeout = getWriteTimeout();
+            if (writeTimeout > 0) {
+                return writeTimeout;
+            }
+            // NIO2 can't do infinite timeout so use Long.MAX_VALUE
+            return Long.MAX_VALUE;
+        }
+
+
         @Override
         protected void populateRemoteAddr() {
             SocketAddress socketAddress = null;
@@ -1495,8 +1510,9 @@ public class Nio2Endpoint extends Abstra
                     }
                 }
             }
-            attachment.socket.getSocket().write(attachment.buffer, attachment.socket.getTimeout(),
-                    TimeUnit.MILLISECONDS, attachment, this);
+            attachment.socket.getSocket().write(attachment.buffer,
+                    attachment.socket.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
+                    attachment, this);
         }
 
         @Override
@@ -1543,7 +1559,7 @@ public class Nio2Endpoint extends Abstra
             data.length -= nRead;
             socket.getSocket().getBufHandler().configureWriteBufferForRead();
             Nio2Endpoint.startInline();
-            socket.getSocket().write(buffer, socket.getTimeout(), TimeUnit.MILLISECONDS,
+            socket.getSocket().write(buffer, socket.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
                     data, sendfile);
             Nio2Endpoint.endInline();
             if (data.doneInline) {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java Thu Jan 29 19:11:47 2015
@@ -366,7 +366,6 @@ public class NioBlockingSelector {
                         SelectionKey sk = iterator.next();
                         NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();
                         try {
-                            attachment.access();
                             iterator.remove();
                             sk.interestOps(sk.interestOps() & (~sk.readyOps()));
                             if ( sk.isReadable() ) {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Thu Jan 29 19:11:47 2015
@@ -772,7 +772,6 @@ public class NioEndpoint extends Abstrac
                     if (key != null) {
                         final NioSocketWrapper att = (NioSocketWrapper) key.attachment();
                         if ( att!=null ) {
-                            att.access();//to prevent timeout
                             //we are registering the key to start with, reset the fairness counter.
                             int ops = key.interestOps() | interestOps;
                             att.interestOps(ops);
@@ -1026,7 +1025,6 @@ public class NioEndpoint extends Abstrac
                         if (attachment == null) {
                             iterator.remove();
                         } else {
-                            attachment.access();
                             iterator.remove();
                             processKey(sk, attachment);
                         }
@@ -1059,7 +1057,6 @@ public class NioEndpoint extends Abstrac
                 if ( close ) {
                     cancelledKey(sk);
                 } else if ( sk.isValid() && attachment != null ) {
-                    attachment.access();//make sure we don't time out valid sockets
                     if (sk.isReadable() || sk.isWritable() ) {
                         if ( attachment.getSendfileData() != null ) {
                             processSendfile(sk,attachment, false);
@@ -1128,14 +1125,14 @@ public class NioEndpoint extends Abstrac
                 // We still have data in the buffer
                 if (sc.getOutboundRemaining()>0) {
                     if (sc.flushOutbound()) {
-                        socketWrapper.access();
+                        socketWrapper.updateLastWrite();
                     }
                 } else {
                     long written = sd.fchannel.transferTo(sd.pos,sd.length,wc);
                     if (written > 0) {
                         sd.pos += written;
                         sd.length -= written;
-                        socketWrapper.access();
+                        socketWrapper.updateLastWrite();
                     } else {
                         // Unusual not to be able to transfer any bytes
                         // Check the length was set correctly
@@ -1229,18 +1226,29 @@ public class NioEndpoint extends Abstrac
                         cancelledKey(key);//TODO this is not yet being used
                     } else if ((ka.interestOps()&SelectionKey.OP_READ) == SelectionKey.OP_READ ||
                               (ka.interestOps()&SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
-                        //only timeout sockets that we are waiting for a read from
-                        long delta = now - ka.getLastAccess();
-                        long timeout = ka.getTimeout();
-                        boolean isTimedout = timeout > 0 && delta > timeout;
-                        if ( close ) {
+                        if (close) {
                             key.interestOps(0);
                             ka.interestOps(0); //avoid duplicate stop calls
                             processKey(key,ka);
-                        } else if (isTimedout) {
-                            key.interestOps(0);
-                            ka.interestOps(0); //avoid duplicate timeout calls
-                            cancelledKey(key);
+                        } else {
+                            boolean isTimedOut = false;
+                            // Check for read timeout
+                            if ((ka.interestOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
+                                long delta = now - ka.getLastRead();
+                                long timeout = ka.getReadTimeout();
+                                isTimedOut = timeout > 0 && delta > timeout;
+                            }
+                            // Check for write timeout
+                            if (!isTimedOut && (ka.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
+                                long delta = now - ka.getLastWrite();
+                                long timeout = ka.getWriteTimeout();
+                                isTimedOut = timeout > 0 && delta > timeout;
+                            }
+                            if (isTimedOut) {
+                                key.interestOps(0);
+                                ka.interestOps(0); //avoid duplicate timeout calls
+                                cancelledKey(key);
+                            }
                         }
                     } else if (ka.isAsync()) {
                         if (close) {
@@ -1250,7 +1258,7 @@ public class NioEndpoint extends Abstrac
                         } else if (ka.getAsyncTimeout() > 0) {
                             if ((now - ka.getLastAsyncStart()) > ka.getAsyncTimeout()) {
                                 // Prevent subsequent timeouts if the timeout event takes a while to process
-                                ka.access(Long.MAX_VALUE);
+                                ka.setAsyncTimeout(0);
                                 processSocket(ka, SocketStatus.TIMEOUT, true);
                             }
                         }
@@ -1282,7 +1290,6 @@ public class NioEndpoint extends Abstrac
         private CountDownLatch readLatch = null;
         private CountDownLatch writeLatch = null;
         private volatile SendfileData sendfileData = null;
-        private long writeTimeout = -1;
 
         public NioSocketWrapper(NioChannel channel, NioEndpoint endpoint) {
             super(channel, endpoint);
@@ -1367,11 +1374,6 @@ public class NioEndpoint extends Abstrac
         public void setSendfileData(SendfileData sf) { this.sendfileData = sf;}
         public SendfileData getSendfileData() { return this.sendfileData;}
 
-        public void setWriteTimeout(long writeTimeout) {
-            this.writeTimeout = writeTimeout;
-        }
-        public long getWriteTimeout() {return this.writeTimeout;}
-
 
         @Override
         public boolean isReadyForRead() throws IOException {
@@ -1473,7 +1475,7 @@ public class NioEndpoint extends Abstrac
                         throw new IOException("Key must be cancelled.");
                     }
                     nRead = pool.read(socketBufferHandler.getReadBuffer(),
-                            channel, selector, att.getTimeout());
+                            channel, selector, att.getReadTimeout());
                 } catch (EOFException eof) {
                     nRead = -1;
                 } finally {
@@ -1489,7 +1491,7 @@ public class NioEndpoint extends Abstrac
 
 
         @Override
-        protected synchronized void doWrite(boolean block) throws IOException {
+        protected synchronized void doWriteInternal(boolean block) throws IOException {
             socketBufferHandler.configureWriteBufferForRead();
 
             long writeTimeout = getWriteTimeout();

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java?rev=1655807&r1=1655806&r2=1655807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Thu Jan 29 19:11:47 2015
@@ -33,10 +33,12 @@ public abstract class SocketWrapperBase<
     private volatile E socket;
     private final AbstractEndpoint<E> endpoint;
 
-    private volatile long lastAccess = System.currentTimeMillis();
+    private volatile long lastRead = 0;
+    private volatile long lastWrite = 0;
     private volatile long lastAsyncStart = 0;
     private volatile long asyncTimeout = -1;
-    private long timeout = -1;
+    private long readTimeout = -1;
+    private long writeTimeout = -1;
     private IOException error = null;
     private volatile int keepAliveLeft = 100;
     private volatile boolean async = false;
@@ -145,13 +147,44 @@ public abstract class SocketWrapperBase<
     public void setUpgraded(boolean upgraded) { this.upgraded = upgraded; }
     public boolean isSecure() { return secure; }
     public void setSecure(boolean secure) { this.secure = secure; }
-    public long getLastAccess() { return lastAccess; }
-    public void access() {
-        access(System.currentTimeMillis());
-    }
-    void access(long access) { lastAccess = access; }
-    public void setTimeout(long timeout) {this.timeout = timeout;}
-    public long getTimeout() {return this.timeout;}
+
+    /**
+     * Set the timeout for reading. Values of zero or less will be changed to]
+     * -1.
+     *
+     * @param readTimeout The timeout in milliseconds. A value of -1 indicates
+     *                    an infinite timeout.
+     */
+    public void setReadTimeout(long readTimeout) {
+        if (readTimeout > 0) {
+            this.readTimeout = readTimeout;
+        } else {
+            this.readTimeout = -1;
+        }
+    }
+
+    public long getReadTimeout() {return this.readTimeout;}
+
+    /**
+     * Set the timeout for writing. Values of zero or less will be changed to
+     * -1.
+     *
+     * @param writeTimeout The timeout in milliseconds. A value of zero or less
+     *                    indicates an infinite timeout.
+     */
+    public void setWriteTimeout(long writeTimeout) {
+        if (writeTimeout > 0) {
+            this.writeTimeout = writeTimeout;
+        } else {
+            this.writeTimeout = -1;
+        }
+    }
+
+    public long getWriteTimeout() {return this.writeTimeout;}
+
+    public void updateLastWrite() { lastWrite = System.currentTimeMillis(); }
+    public long getLastWrite() { return lastWrite; }
+    public long getLastRead() { return lastRead; }
     public IOException getError() { return error; }
     public void setError(IOException error) { this.error = error; }
     public void setKeepAliveLeft(int keepAliveLeft) { this.keepAliveLeft = keepAliveLeft;}
@@ -278,13 +311,14 @@ public abstract class SocketWrapperBase<
         }
     }
 
-    public void reset(E socket, long timeout) {
+    public void reset(E socket, long soTimeout) {
         async = false;
         blockingStatus = true;
         dispatches.clear();
         error = null;
         keepAliveLeft = 100;
-        lastAccess = System.currentTimeMillis();
+        lastRead = 0;
+        lastWrite = 0;
         lastAsyncStart = 0;
         asyncTimeout = -1;
         localAddr = null;
@@ -294,7 +328,8 @@ public abstract class SocketWrapperBase<
         remoteHost = null;
         remotePort = -1;
         this.socket = socket;
-        this.timeout = timeout;
+        this.readTimeout = soTimeout;
+        this.writeTimeout = soTimeout;
         upgraded = false;
         resetSocketBufferHandler(socket);
     }
@@ -343,11 +378,13 @@ public abstract class SocketWrapperBase<
      *
      * @throws IOException If an IO error occurs during the write
      */
-    public void write(boolean block, byte[] buf, int off, int len) throws IOException {
+    public final void write(boolean block, byte[] buf, int off, int len) throws IOException {
         if (len == 0 || buf == null || getSocket() == null) {
             return;
         }
 
+        lastWrite = System.currentTimeMillis();
+
         // While the implementations for blocking and non-blocking writes are
         // very similar they have been split into separate methods to allow
         // sub-classes to override them individually. NIO2, for example,
@@ -357,9 +394,6 @@ public abstract class SocketWrapperBase<
         } else {
             writeNonBlocking(buf, off, len);
         }
-
-        // Prevent timeouts
-        access();
     }
 
 
@@ -460,9 +494,6 @@ public abstract class SocketWrapperBase<
             result = flushNonBlocking();
         }
 
-        // Prevent timeouts
-        access();
-
         return result;
     }
 
@@ -518,6 +549,20 @@ public abstract class SocketWrapperBase<
         return !socketBufferHandler.isWriteBufferEmpty();
     }
 
+    /**
+     * Write the contents of the socketWriteBuffer to the socket. For blocking
+     * writes either then entire contents of the buffer will be written or an
+     * IOException will be thrown. Partial blocking writes will not occur.
+     *
+     * @param block Should the write be blocking or not?
+     *
+     * @throws IOException If an I/O error such as a timeout occurs during the
+     *                     write
+     */
+    protected final void doWrite(boolean block) throws IOException {
+        lastWrite = System.currentTimeMillis();
+        doWriteInternal(block);
+    }
 
     /**
      * Write the contents of the socketWriteBuffer to the socket. For blocking
@@ -529,7 +574,7 @@ public abstract class SocketWrapperBase<
      * @throws IOException If an I/O error such as a timeout occurs during the
      *                     write
      */
-    protected abstract void doWrite(boolean block) throws IOException;
+    protected abstract void doWriteInternal(boolean block) throws IOException;
 
 
     protected void addToBuffers(byte[] buf, int offset, int length) {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org