Author: markt Date: Sat Feb 2 20:38:29 2013 New Revision: 1441807 URL: http://svn.apache.org/viewvc?rev=1441807&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54513 Multiple bugs in the new Poller implementation (r1433976) when the endpoint is stopped and then started - Ensure old Poller thread stops - Ensure old AsyncTimeout thread stops - Ensure old sendfile thread stops - Ensure sockets in keep-alive are closed
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java 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=1441807&r1=1441806&r2=1441807&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Sat Feb 2 20:38:29 2013 @@ -186,6 +186,15 @@ public class AprEndpoint extends Abstrac /** + * The socket poller. + */ + protected AsyncTimeout asyncTimeout = null; + public AsyncTimeout getAsyncTimeout() { + return asyncTimeout; + } + + + /** * The static file sender. */ protected Sendfile sendfile = null; @@ -609,7 +618,8 @@ public class AprEndpoint extends Abstrac startAcceptorThreads(); // Start async timeout thread - Thread timeoutThread = new Thread(new AsyncTimeout(), + asyncTimeout = new AsyncTimeout(); + Thread timeoutThread = new Thread(asyncTimeout, getName() + "-AsyncTimeout"); timeoutThread.setPriority(threadPriority); timeoutThread.setDaemon(true); @@ -629,6 +639,8 @@ public class AprEndpoint extends Abstrac } if (running) { running = false; + poller.stop(); + asyncTimeout.stop(); unlockAccept(); for (AbstractEndpoint.Acceptor acceptor : acceptors) { long waitLeft = 10000; @@ -1000,6 +1012,9 @@ public class AprEndpoint extends Abstrac * Async timeout thread */ protected class AsyncTimeout implements Runnable { + + private volatile boolean asyncTimeoutRunning = true; + /** * The background thread that checks async requests and fires the * timeout if there has been no activity. @@ -1008,7 +1023,7 @@ public class AprEndpoint extends Abstrac public void run() { // Loop until we receive a shutdown command - while (running) { + while (asyncTimeoutRunning) { try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -1029,7 +1044,7 @@ public class AprEndpoint extends Abstrac } // Loop if endpoint is paused - while (paused && running) { + while (paused && asyncTimeoutRunning) { try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -1039,6 +1054,11 @@ public class AprEndpoint extends Abstrac } } + + + protected void stop() { + asyncTimeoutRunning = false; + } } @@ -1260,6 +1280,8 @@ public class AprEndpoint extends Abstrac public int getConnectionCount() { return connectionCount; } + private volatile boolean pollerRunning = true; + /** * Create the poller. With some versions of APR, the maximum poller size * will be 62 (recompiling APR is necessary to remove this limitation). @@ -1316,6 +1338,12 @@ public class AprEndpoint extends Abstrac } + + protected void stop() { + pollerRunning = false; + } + + /** * Destroy the poller. */ @@ -1325,6 +1353,7 @@ public class AprEndpoint extends Abstrac // still in the poller can cause problems try { synchronized (this) { + this.notify(); this.wait(pollTime / 1000); } } catch (InterruptedException e) { @@ -1351,7 +1380,7 @@ public class AprEndpoint extends Abstrac Long.valueOf(desc[n*2+1])).isComet(); if (!comet || (comet && !processSocket( desc[n*2+1], SocketStatus.STOP))) { - destroySocket(desc[n*2+1]); + destroySocket(desc[n*2+1], true); } } } @@ -1537,7 +1566,7 @@ public class AprEndpoint extends Abstrac int maintain = 0; // Loop until we receive a shutdown command - while (running) { + while (pollerRunning) { // Loop if endpoint is paused while (paused) { @@ -1548,10 +1577,11 @@ public class AprEndpoint extends Abstrac } } // Check timeouts if the poller is empty - while (connectionCount < 1 && addList.size() < 1) { + while (pollerRunning && connectionCount < 1 && + addList.size() < 1) { // Reset maintain time. try { - if (getSoTimeout() > 0 && running) { + if (getSoTimeout() > 0 && pollerRunning) { maintain(); } synchronized (this) { @@ -1722,7 +1752,7 @@ public class AprEndpoint extends Abstrac } // Process socket timeouts - if (getSoTimeout() > 0 && maintain++ > 1000 && running) { + if (getSoTimeout() > 0 && maintain++ > 1000 && pollerRunning) { // This works and uses only one timeout mechanism for everything, but the // non event poller might be a bit faster by using the old maintain. maintain = 0; @@ -1785,6 +1815,8 @@ public class AprEndpoint extends Abstrac protected ArrayList<SendfileData> addS; + private volatile boolean sendfileRunning = true; + /** * Create the sendfile poller. With some versions of APR, the maximum * poller size will be 62 (recompiling APR is necessary to remove this @@ -1814,6 +1846,7 @@ public class AprEndpoint extends Abstrac * Destroy the poller. */ protected void destroy() { + sendfileRunning = false; // Wait for polltime before doing anything, so that the poller threads // exit, otherwise parallel destruction of sockets which are still // in the poller can cause problems @@ -1920,7 +1953,7 @@ public class AprEndpoint extends Abstrac long maintainTime = 0; // Loop until we receive a shutdown command - while (running) { + while (sendfileRunning) { // Loop if endpoint is paused while (paused) { @@ -2036,7 +2069,7 @@ public class AprEndpoint extends Abstrac } // Call maintain for the sendfile poller if (getSoTimeout() > 0 && - maintainTime > 1000000L && running) { + maintainTime > 1000000L && sendfileRunning) { rv = Poll.maintain(sendfilePollset, desc, false); maintainTime = 0; if (rv > 0) { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org