Author: markt
Date: Fri May 22 14:02:54 2015
New Revision: 1681123
URL: http://svn.apache.org/r1681123
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57943
Catch the ConcurrentModificationException so the Poller thread does not stop.
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1681123&r1=1681122&r2=1681123&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Fri
May 22 14:02:54 2015
@@ -75,6 +75,7 @@ endpoint.apr.pollUnknownEvent=A socket w
endpoint.apr.remoteport=APR socket [{0}] opened with remote port [{1}]
endpoint.jsse.noSslContext=No SSLContext could be found for the host name [{0}]
endpoint.nio.selectorCloseFail=Failed to close selector when closing the poller
+endpoint.nio.timeoutCme=Exception during processing of timeouts. The code has
been checked repeatedly and no concurrent modification has been found. If you
are able to repeat this error please open a Tomcat bug and provide the steps to
reproduce.
endpoint.nio2.exclusiveExecutor=The NIO2 connector requires an exclusive
executor to operate properly on shutdown
channel.nio.interrupted=The current thread was interrupted
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=1681123&r1=1681122&r2=1681123&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Fri May 22
14:02:54 2015
@@ -33,6 +33,7 @@ import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
+import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -1039,57 +1040,62 @@ public class NioEndpoint extends Abstrac
}
//timeout
int keycount = 0;
- for (SelectionKey key : selector.keys()) {
- keycount++;
- try {
- NioSocketWrapper ka = (NioSocketWrapper) key.attachment();
- if ( ka == null ) {
- cancelledKey(key); //we don't support any keys without
attachments
- } else if ( ka.getError() != null) {
- 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) {
- if (close) {
- key.interestOps(0);
- ka.interestOps(0); //avoid duplicate stop calls
- processKey(key,ka);
- } 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) {
+ try {
+ for (SelectionKey key : selector.keys()) {
+ keycount++;
+ try {
+ NioSocketWrapper ka = (NioSocketWrapper)
key.attachment();
+ if ( ka == null ) {
+ cancelledKey(key); //we don't support any keys
without attachments
+ } else if ( ka.getError() != null) {
+ 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) {
+ if (close) {
key.interestOps(0);
- ka.interestOps(0); //avoid duplicate timeout
calls
- cancelledKey(key);
+ ka.interestOps(0); //avoid duplicate stop calls
+ processKey(key,ka);
+ } 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) {
- key.interestOps(0);
- ka.interestOps(0); //avoid duplicate stop calls
- processKey(key,ka);
- } else if (ka.getAsyncTimeout() > 0) {
- if ((now - ka.getLastAsyncStart()) >
ka.getAsyncTimeout()) {
- // Prevent subsequent timeouts if the timeout
event takes a while to process
- ka.setAsyncTimeout(0);
- processSocket(ka, SocketStatus.TIMEOUT, true);
+ } else if (ka.isAsync()) {
+ if (close) {
+ key.interestOps(0);
+ ka.interestOps(0); //avoid duplicate stop calls
+ processKey(key,ka);
+ } else if (ka.getAsyncTimeout() > 0) {
+ if ((now - ka.getLastAsyncStart()) >
ka.getAsyncTimeout()) {
+ // Prevent subsequent timeouts if the
timeout event takes a while to process
+ ka.setAsyncTimeout(0);
+ processSocket(ka, SocketStatus.TIMEOUT,
true);
+ }
}
- }
- }//end if
- }catch ( CancelledKeyException ckx ) {
- cancelledKey(key);
- }
- }//for
+ }//end if
+ }catch ( CancelledKeyException ckx ) {
+ cancelledKey(key);
+ }
+ }//for
+ } catch (ConcurrentModificationException cme) {
+ // See https://bz.apache.org/bugzilla/show_bug.cgi?id=57943
+ log.warn(sm.getString("endpoint.nio.timeoutCme"), cme);
+ }
long prevExp = nextExpiration; //for logging purposes only
nextExpiration = System.currentTimeMillis() +
socketProperties.getTimeoutInterval();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]