Author: markt Date: Tue Jun 10 09:52:56 2014 New Revision: 1601590 URL: http://svn.apache.org/r1601590 Log: Pull up AsyncTimeout APR/native used a separate flag to stop the thread. This avoided issues where running was set true->false-true in quick succession. This fix is now available to NIO2 and BIO as well. Note NIO does not (currently) use the AsyncTimeout
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1601590&r1=1601589&r2=1601590&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Tue Jun 10 09:52:56 2014 @@ -99,6 +99,60 @@ public abstract class AbstractEndpoint<S private static final int INITIAL_ERROR_DELAY = 50; private static final int MAX_ERROR_DELAY = 1600; + + /** + * 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. + */ + @Override + public void run() { + + // Loop until we receive a shutdown command + while (asyncTimeoutRunning) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // Ignore + } + long now = System.currentTimeMillis(); + Iterator<SocketWrapper<S>> sockets = waitingRequests.keySet().iterator(); + while (sockets.hasNext()) { + SocketWrapper<S> socket = sockets.next(); + if (socket.isAsync()) { + long access = socket.getLastAccess(); + if (socket.getTimeout() > 0 && + (now-access) > socket.getTimeout()) { + processSocket(socket, SocketStatus.TIMEOUT, true); + } + } + } + + // Loop if endpoint is paused + while (paused && asyncTimeoutRunning) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // Ignore + } + } + + } + } + + + protected void stop() { + asyncTimeoutRunning = false; + } + } + + // ----------------------------------------------------------------- Fields @@ -977,5 +1031,17 @@ public abstract class AbstractEndpoint<S protected ConcurrentHashMap<SocketWrapper<S>, SocketWrapper<S>> waitingRequests = new ConcurrentHashMap<>(); + + + /** + * The async timeout thread. + */ + private AsyncTimeout asyncTimeout = null; + public AsyncTimeout getAsyncTimeout() { + return asyncTimeout; + } + public void setAsyncTimeout(AsyncTimeout asyncTimeout) { + this.asyncTimeout = asyncTimeout; + } } 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=1601590&r1=1601589&r2=1601590&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Tue Jun 10 09:52:56 2014 @@ -18,7 +18,6 @@ package org.apache.tomcat.util.net; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -191,15 +190,6 @@ 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; @@ -640,9 +630,8 @@ public class AprEndpoint extends Abstrac startAcceptorThreads(); // Start async timeout thread - asyncTimeout = new AsyncTimeout(); - Thread timeoutThread = new Thread(asyncTimeout, - getName() + "-AsyncTimeout"); + setAsyncTimeout(new AsyncTimeout()); + Thread timeoutThread = new Thread(getAsyncTimeout(), getName() + "-AsyncTimeout"); timeoutThread.setPriority(threadPriority); timeoutThread.setDaemon(true); timeoutThread.start(); @@ -662,7 +651,7 @@ public class AprEndpoint extends Abstrac if (running) { running = false; poller.stop(); - asyncTimeout.stop(); + getAsyncTimeout().stop(); unlockAccept(); for (AbstractEndpoint.Acceptor acceptor : acceptors) { long waitLeft = 10000; @@ -1048,59 +1037,6 @@ 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. - */ - @Override - public void run() { - - // Loop until we receive a shutdown command - while (asyncTimeoutRunning) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - long now = System.currentTimeMillis(); - Iterator<SocketWrapper<Long>> sockets = waitingRequests.keySet().iterator(); - while (sockets.hasNext()) { - SocketWrapper<Long> socket = sockets.next(); - if (socket.isAsync()) { - long access = socket.getLastAccess(); - if (socket.getTimeout() > 0 && - (now-access) > socket.getTimeout()) { - processSocket(socket, SocketStatus.TIMEOUT, true); - } - } - } - - // Loop if endpoint is paused - while (paused && asyncTimeoutRunning) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - } - - } - } - - - protected void stop() { - asyncTimeoutRunning = false; - } - } - - // -------------------------------------------------- SocketInfo Inner Class public static class SocketInfo { Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1601590&r1=1601589&r2=1601590&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Tue Jun 10 09:52:56 2014 @@ -21,7 +21,6 @@ import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; -import java.util.Iterator; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; @@ -143,51 +142,6 @@ public class JIoEndpoint extends Abstrac } - /** - * Async timeout thread - */ - protected class AsyncTimeout implements Runnable { - /** - * The background thread that checks async requests and fires the - * timeout if there has been no activity. - */ - @Override - public void run() { - - // Loop until we receive a shutdown command - while (running) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - long now = System.currentTimeMillis(); - Iterator<SocketWrapper<Socket>> sockets = waitingRequests.keySet().iterator(); - while (sockets.hasNext()) { - SocketWrapper<Socket> socket = sockets.next(); - if (socket.isAsync()) { - long access = socket.getLastAccess(); - if (socket.getTimeout() > 0 && - (now-access) > socket.getTimeout()) { - processSocket(socket, SocketStatus.TIMEOUT, true); - } - } - } - - // Loop if endpoint is paused - while (paused && running) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - } - - } - } - } - - // --------------------------------------------------- Acceptor Inner Class /** * The background thread that listens for incoming TCP/IP connections and @@ -441,8 +395,8 @@ public class JIoEndpoint extends Abstrac startAcceptorThreads(); // Start async timeout thread - Thread timeoutThread = new Thread(new AsyncTimeout(), - getName() + "-AsyncTimeout"); + setAsyncTimeout(new AsyncTimeout()); + Thread timeoutThread = new Thread(getAsyncTimeout(), getName() + "-AsyncTimeout"); timeoutThread.setPriority(threadPriority); timeoutThread.setDaemon(true); timeoutThread.start(); @@ -457,6 +411,7 @@ public class JIoEndpoint extends Abstrac } if (running) { running = false; + getAsyncTimeout().stop(); unlockAccept(); } shutdownExecutor(); 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=1601590&r1=1601589&r2=1601590&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Tue Jun 10 09:52:56 2014 @@ -30,7 +30,6 @@ import java.nio.channels.ClosedChannelEx import java.nio.channels.CompletionHandler; import java.nio.channels.FileChannel; import java.nio.file.StandardOpenOption; -import java.util.Iterator; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; @@ -360,9 +359,8 @@ public class Nio2Endpoint extends Abstra initializeConnectionLatch(); startAcceptorThreads(); - // Start async timeout thread - Thread timeoutThread = new Thread(new AsyncTimeout(), - getName() + "-AsyncTimeout"); + setAsyncTimeout(new AsyncTimeout()); + Thread timeoutThread = new Thread(getAsyncTimeout(), getName() + "-AsyncTimeout"); timeoutThread.setPriority(threadPriority); timeoutThread.setDaemon(true); timeoutThread.start(); @@ -381,6 +379,7 @@ public class Nio2Endpoint extends Abstra } if (running) { running = false; + getAsyncTimeout().stop(); unlockAccept(); } // Use the executor to avoid binding the main thread if something bad @@ -736,51 +735,6 @@ public class Nio2Endpoint extends Abstra } - /** - * Async timeout thread - */ - protected class AsyncTimeout implements Runnable { - /** - * The background thread that checks async requests and fires the - * timeout if there has been no activity. - */ - @Override - public void run() { - - // Loop until we receive a shutdown command - while (running) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - long now = System.currentTimeMillis(); - Iterator<SocketWrapper<Nio2Channel>> sockets = - waitingRequests.keySet().iterator(); - while (sockets.hasNext()) { - SocketWrapper<Nio2Channel> socket = sockets.next(); - if (socket.isAsync()) { - long access = socket.getLastAccess(); - if (socket.getTimeout() > 0 && - (now-access) > socket.getTimeout()) { - processSocket(socket, SocketStatus.TIMEOUT, true); - } - } - } - - // Loop if endpoint is paused - while (paused && running) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore - } - } - - } - } - } - private void closeSocket(AsynchronousSocketChannel socket) { try { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org