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