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