Author: fhanik Date: Mon Dec 21 19:52:50 2009 New Revision: 892944 URL: http://svn.apache.org/viewvc?rev=892944&view=rev Log: Add unlockTimeout
Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SocketProperties.java tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml tomcat/tc6.0.x/trunk/webapps/docs/config/http.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=892944&r1=892943&r2=892944&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Mon Dec 21 19:52:50 2009 @@ -67,34 +67,6 @@ -1: remm: no for TC 6.0 -1: funkman : api change in Session.java for .x.x release -* Improve NIO connector shutdown time by doing shutdowns in parallel - and with a timeout - http://svn.apache.org/viewvc?view=rev&revision=791914 - +1: fhanik, markt, kkolinko, jim - -1: - kkolinko: ( - Some nit-picking: - 1. I think that it is better to create the stopLatch in the NioEndpoint#start() - method right before the array of Pollers is created, instead of NioEndpoint#init(). - And to pass a reference to it to the Poller (as an argument in Poller - constructor). - That is because otherwise if you call stop() start() the stopLatch won't be in - its initial condition, and because the count of pollers can be changed between - init() and start(). Just a theory, though. - - 2. In NioEndpoint.Poller#run(): - - if the Poller was looping with paused=true, is there a need to call - events() before exiting the loop on if (close) ? - - there are several ways to exit the loop: two if(close), one while - (running), and may be exceptions. The first if(close) does not call - selector.close(). And if you exit because of running = false there is - no call to timeout(0, false); and selector.close(). - - there is special processing code for OutOfMemoryError, but inside the - loop, and in events() method, you catch any Throwable. - - it would be better to put stopLatch.countDown() inside a finally{} block - 3. In NioEndpoint.Poller#destroy() there is comment ("// Wait..."). - Is it still relevant? I do not see any waiting there. - ) * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=47893 Use StringBuilder instead of StringBuffer Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=892944&r1=892943&r2=892944&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Mon Dec 21 19:52:50 2009 @@ -23,6 +23,8 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketTimeoutException; import java.nio.ByteBuffer; import java.nio.channels.CancelledKeyException; import java.nio.channels.FileChannel; @@ -195,7 +197,10 @@ */ protected AtomicInteger activeSocketProcessors = new AtomicInteger(0); - + /** + * + */ + protected volatile CountDownLatch stopLatch = null; /** * Cache for SocketProcessor objects @@ -804,6 +809,7 @@ InetSocketAddress addr = (address!=null?new InetSocketAddress(address,port):new InetSocketAddress(port)); serverSock.socket().bind(addr,backlog); serverSock.configureBlocking(true); //mimic APR behavior + serverSock.socket().setSoTimeout(getSocketProperties().getSoTimeout()); // Initialize thread count defaults for acceptor, poller if (acceptorThreadCount == 0) { @@ -814,6 +820,7 @@ //minimum one poller thread pollerThreadCount = 1; } + stopLatch = new CountDownLatch(pollerThreadCount); // Initialize SSL if needed if (isSSLEnabled()) { @@ -949,6 +956,7 @@ pollers[i].destroy(); pollers[i] = null; } + try { stopLatch.await(selectorTimeout+100,TimeUnit.MILLISECONDS); } catch (InterruptedException ignore ) {} } eventCache.clear(); keyCache.clear(); @@ -958,7 +966,7 @@ if ( executor instanceof ThreadPoolExecutor ) { //this is our internal one, so we need to shut it down ThreadPoolExecutor tpe = (ThreadPoolExecutor) executor; - tpe.shutdown(); + tpe.shutdownNow(); TaskQueue queue = (TaskQueue) tpe.getQueue(); queue.setParent(null,null); } @@ -972,6 +980,9 @@ * Deallocate NIO memory pools, and close server socket. */ public void destroy() throws Exception { + if (log.isDebugEnabled()) { + log.debug("Destroy initiated for "+new InetSocketAddress(address,port)); + } if (running) { stop(); } @@ -983,6 +994,9 @@ initialized = false; releaseCaches(); selectorPool.close(); + if (log.isDebugEnabled()) { + log.debug("Destroy completed for "+new InetSocketAddress(address,port)); + } } @@ -1030,16 +1044,24 @@ */ protected void unlockAccept() { java.net.Socket s = null; + InetSocketAddress saddr = null; try { // Need to create a connection to unlock the accept(); if (address == null) { - s = new java.net.Socket(InetAddress.getByName("localhost").getHostAddress(), port); + saddr = new InetSocketAddress("127.0.0.1", port); } else { - s = new java.net.Socket(address, port); - // setting soLinger to a small value will help shutdown the - // connection quicker - s.setSoLinger(true, 0); + saddr = new InetSocketAddress(address,port); + } + s = new java.net.Socket(); + s.setSoTimeout(getSocketProperties().getSoTimeout()); + s.setSoLinger(getSocketProperties().getSoLingerOn(),getSocketProperties().getSoLingerTime()); + if (log.isDebugEnabled()) { + log.debug("About to unlock socket for:"+saddr); } + s.connect(saddr,getSocketProperties().getUnlockTimeout()); + if (log.isDebugEnabled()) { + log.debug("Socket unlock completed for:"+saddr); + } } catch(Exception e) { if (log.isDebugEnabled()) { log.debug(sm.getString("endpoint.debug.unlock", "" + port), e); @@ -1302,6 +1324,8 @@ } } } + }catch (SocketTimeoutException sx) { + //normal condition }catch ( IOException x ) { if ( running ) log.error(sm.getString("endpoint.accept.fail"), x); } catch (OutOfMemoryError oom) { @@ -1405,7 +1429,7 @@ protected Selector selector; protected ConcurrentLinkedQueue<Runnable> events = new ConcurrentLinkedQueue<Runnable>(); - protected boolean close = false; + protected volatile boolean close = false; protected long nextExpiration = 0;//optimize expiration handling protected AtomicLong wakeupCounter = new AtomicLong(0l); @@ -1425,12 +1449,11 @@ */ protected void destroy() { // Wait for polltime before doing anything, so that the poller threads - // exit, otherwise parallel descturction of sockets which are still + // exit, otherwise parallel closure of sockets which are still // in the poller can cause problems close = true; events.clear(); selector.wakeup(); - try { stopLatch.await(5,TimeUnit.SECONDS); } catch (InterruptedException ignore ) {} } public void addEvent(Runnable event) { @@ -1542,7 +1565,7 @@ // Loop if endpoint is paused while (paused && (!close) ) { try { - Thread.sleep(500); + Thread.sleep(100); } catch (InterruptedException e) { // Ignore } @@ -1553,8 +1576,7 @@ // Time to terminate? if (close) { timeout(0, false); - stopLatch.countDown(); - return; + break; } int keyCount = 0; try { @@ -1571,9 +1593,8 @@ } if (close) { timeout(0, false); - stopLatch.countDown(); selector.close(); - return; + break; } } catch ( NullPointerException x ) { //sun bug 5076772 on windows JDK 1.5 Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SocketProperties.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SocketProperties.java?rev=892944&r1=892943&r2=892944&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SocketProperties.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SocketProperties.java Mon Dec 21 19:52:50 2009 @@ -162,6 +162,11 @@ * poller going boinkers during high traffic */ protected long timeoutInterval = 1000; + + /** + * Timeout in milliseconds for an unlock to take place. + */ + protected int unlockTimeout = 250; private Socket properties; @@ -367,4 +372,14 @@ this.bufferPool = directBufferPool; } + public int getUnlockTimeout() { + return unlockTimeout; + } + + public void setUnlockTimeout(int unlockTimeout) { + this.unlockTimeout = unlockTimeout; + } + + + } \ No newline at end of file Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=892944&r1=892943&r2=892944&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Mon Dec 21 19:52:50 2009 @@ -382,6 +382,7 @@ </subsection> <subsection name="Coyote"> <changelog> + <update>Implement <code>socket.unlockTimeout</code> attribute for NIO connector.</update> <fix> <bug>46950</bug>: Fix doing SSL renegotiation when a resource with CLIENT-CERT auth is requested. (markt) Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/http.xml?rev=892944&r1=892943&r2=892944&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/config/http.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/config/http.xml Mon Dec 21 19:52:50 2009 @@ -583,6 +583,10 @@ If you have an OOM outside of the Java Heap, then this parachute trick will not help. </p> </attribute> + <attribute name="socket.unlockTimeout" required="false"> + <p>(int) The timeout for a socket unlock. When a connector is stopped, it will try to release the acceptor thread by opening a connector to itself. + The default value is <code>250</code> and the value is in milliseconds</p> + </attribute> </attributes> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org