Author: remm Date: Fri Mar 21 19:50:11 2014 New Revision: 1580031 URL: http://svn.apache.org/r1580031 Log: - Actually follow the instructions on proper NIO2 shutdown. Much cleaner indeed. - The downside is that the executor is exclusive to the thread group (no way around this), so it cannot be shared with other connectors. - Add a warning if using a shared executor.
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties 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=1580031&r1=1580030&r2=1580031&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Fri Mar 21 19:50:11 2014 @@ -93,6 +93,11 @@ public class Nio2Endpoint extends Abstra private static ThreadLocal<Boolean> inlineCompletion = new ThreadLocal<>(); /** + * Thread group associated with the server socket. + */ + private AsynchronousChannelGroup threadGroup = null; + + /** * The oom parachute, when an OOM error happens, * will release the data, giving the JVM instantly * a chunk of data to be able to recover with. @@ -288,10 +293,13 @@ public class Nio2Endpoint extends Abstra if ( getExecutor() == null ) { createExecutor(); } - AsynchronousChannelGroup threadGroup = null; if (getExecutor() instanceof ExecutorService) { threadGroup = AsynchronousChannelGroup.withThreadPool((ExecutorService) getExecutor()); } + // AsynchronousChannelGroup currently needs exclusive access to its executor service + if (!internalExecutor) { + log.warn(sm.getString("endpoint.nio2.exclusiveExecutor")); + } serverSock = AsynchronousServerSocketChannel.open(threadGroup); socketProperties.setProperties(serverSock); @@ -420,6 +428,32 @@ public class Nio2Endpoint extends Abstra } + @Override + public void shutdownExecutor() { + if (threadGroup != null && internalExecutor) { + try { + threadGroup.shutdownNow(); + } catch (IOException e) { + getLog().warn(sm.getString("endpoint.warn.executorShutdown", getName()), e); + } + long timeout = getExecutorTerminationTimeoutMillis(); + if (timeout > 0) { + try { + threadGroup.awaitTermination(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Ignore + } + if (!threadGroup.isTerminated()) { + getLog().warn(sm.getString("endpoint.warn.executorShutdown", getName())); + } + } + threadGroup = null; + } + // Mostly to cleanup references + super.shutdownExecutor(); + } + + // ------------------------------------------------------ Protected Methods Modified: tomcat/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties?rev=1580031&r1=1580030&r2=1580031&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties Fri Mar 21 19:50:11 2014 @@ -59,3 +59,4 @@ endpoint.apr.pollError=Poller failed wit endpoint.apr.pollUnknownEvent=A socket was returned from the poller with an unrecognized event [{0}] endpoint.apr.remoteport=APR socket [{0}] opened with remote port [{1}] endpoint.nio.selectorCloseFail=Failed to close selector when closing the poller +endpoint.nio2.exclusiveExecutor=The NIO2 connector requires an exclusive executor to operate properly --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org