Author: fhanik Date: Wed May 2 17:15:46 2012 New Revision: 1333116 URL: http://svn.apache.org/viewvc?rev=1333116&view=rev Log: https://issues.apache.org/bugzilla/show_bug.cgi?id=53173 Properly count down maxConnections
Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/threads/LimitLatch.java tomcat/tc7.0.x/trunk/webapps/docs/config/ajp.xml tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java Wed May 2 17:15:46 2012 @@ -541,6 +541,12 @@ public abstract class AbstractProtocol i SocketStatus status) { Processor<S> processor = connections.remove(socket.getSocket()); + if (status == SocketStatus.DISCONNECT && processor == null) { + //nothing more to be done endpoint requested a close + //and there are no object associated with this connection + return SocketState.CLOSED; + } + socket.setAsync(false); try { @@ -555,7 +561,9 @@ public abstract class AbstractProtocol i SocketState state = SocketState.CLOSED; do { - if (processor.isAsync() || state == SocketState.ASYNC_END) { + if (status == SocketStatus.DISCONNECT) { + //do nothing here, just wait for it to get recycled + } else if (processor.isAsync() || state == SocketState.ASYNC_END) { state = processor.asyncDispatch(status); } else if (processor.isComet()) { state = processor.event(status); Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Wed May 2 17:15:46 2012 @@ -163,7 +163,12 @@ public abstract class AbstractEndpoint { LimitLatch latch = this.connectionLimitLatch; if (latch != null) { // Update the latch that enforces this + if (maxCon == -1) + releaseConnectionLatch(); + else latch.setLimit(maxCon); + } else if (maxCon > 0) { + initializeConnectionLatch(); } } @@ -655,6 +660,7 @@ public abstract class AbstractEndpoint { public abstract boolean getUsePolling(); protected LimitLatch initializeConnectionLatch() { + if (maxConnections==-1) return null; if (connectionLimitLatch==null) { connectionLimitLatch = new LimitLatch(getMaxConnections()); } @@ -668,11 +674,13 @@ public abstract class AbstractEndpoint { } protected void countUpOrAwaitConnection() throws InterruptedException { + if (maxConnections==-1) return; LimitLatch latch = connectionLimitLatch; if (latch!=null) latch.countUpOrAwait(); } protected long countDownConnection() { + if (maxConnections==-1) return -1; LimitLatch latch = connectionLimitLatch; if (latch!=null) { long result = latch.countDown(); Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Wed May 2 17:15:46 2012 @@ -991,6 +991,8 @@ public class AprEndpoint extends Abstrac // socket socket = Socket.accept(serverSock); } catch (Exception e) { + //we didn't get a socket + countDownConnection(); // Introduce delay if necessary errorDelay = handleExceptionWithDelay(errorDelay); // re-throw @@ -1002,10 +1004,12 @@ public class AprEndpoint extends Abstrac if (running && !paused) { // Hand this socket off to an appropriate processor if (!processSocketWithOptions(socket)) { + countDownConnection(); // Close socket and pool right away destroySocket(socket); } } else { + countDownConnection(); // Close socket and pool right away destroySocket(socket); } Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Wed May 2 17:15:46 2012 @@ -215,6 +215,7 @@ public class JIoEndpoint extends Abstrac // socket socket = serverSocketFactory.acceptSocket(serverSocket); } catch (IOException ioe) { + countDownConnection(); // Introduce delay if necessary errorDelay = handleExceptionWithDelay(errorDelay); // re-throw @@ -227,10 +228,12 @@ public class JIoEndpoint extends Abstrac if (running && !paused && setSocketOptions(socket)) { // Hand this socket off to an appropriate processor if (!processSocket(socket)) { + countDownConnection(); // Close socket right away closeSocket(socket); } } else { + countDownConnection(); // Close socket right away closeSocket(socket); } @@ -334,6 +337,16 @@ public class JIoEndpoint extends Abstrac if (launch) { try { getExecutor().execute(new SocketProcessor(socket, SocketStatus.OPEN)); + } catch (RejectedExecutionException x) { + log.warn("Socket reprocessing request was rejected for:"+socket,x); + try { + //unable to handle connection at this time + handler.process(socket, SocketStatus.DISCONNECT); + } finally { + countDownConnection(); + } + + } catch (NullPointerException npe) { if (running) { log.error(sm.getString("endpoint.launch.fail"), @@ -559,6 +572,7 @@ public class JIoEndpoint extends Abstrac return false; } getExecutor().execute(proc); + //TODO gotta catch RejectedExecutionException and properly handle it } finally { if (Constants.IS_SECURITY_ENABLED) { PrivilegedAction<Void> pa = new PrivilegedSetTccl(loader); Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Wed May 2 17:15:46 2012 @@ -786,6 +786,8 @@ public class NioEndpoint extends Abstrac // socket socket = serverSock.accept(); } catch (IOException ioe) { + //we didn't get a socket + countDownConnection(); // Introduce delay if necessary errorDelay = handleExceptionWithDelay(errorDelay); // re-throw @@ -798,9 +800,11 @@ public class NioEndpoint extends Abstrac // if successful if (running && !paused) { if (!setSocketOptions(socket)) { + countDownConnection(); closeSocket(socket); } } else { + countDownConnection(); closeSocket(socket); } } catch (SocketTimeoutException sx) { Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/threads/LimitLatch.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/threads/LimitLatch.java?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/threads/LimitLatch.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/threads/LimitLatch.java Wed May 2 17:15:46 2012 @@ -20,6 +20,9 @@ import java.util.Collection; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + /** * Shared latch that allows the latch to be acquired a limited number of times * after which all subsequent requests to acquire the latch will be placed in a @@ -27,6 +30,8 @@ import java.util.concurrent.locks.Abstra */ public class LimitLatch { + private static final Log log = LogFactory.getLog(LimitLatch.class); + private class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 1L; @@ -68,6 +73,14 @@ public class LimitLatch { } /** + * Returns the current count for the latch + * @return the current count for latch + */ + public long getCount() { + return count.get(); + } + + /** * Obtain the current limit. */ public long getLimit() { @@ -96,6 +109,9 @@ public class LimitLatch { * latch is current available. */ public void countUpOrAwait() throws InterruptedException { + if (log.isDebugEnabled()) { + log.debug("Counting up["+Thread.currentThread().getName()+"] latch="+getCount()); + } sync.acquireSharedInterruptibly(1); } @@ -105,7 +121,11 @@ public class LimitLatch { */ public long countDown() { sync.releaseShared(0); - return count.get(); + long result = getCount(); + if (log.isDebugEnabled()) { + log.debug("Counting down["+Thread.currentThread().getName()+"] latch="+result); + } + return result; } /** Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/ajp.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/ajp.xml?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/config/ajp.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/config/ajp.xml Wed May 2 17:15:46 2012 @@ -349,7 +349,9 @@ For APR/native, the default is <code>8192</code>.</p> <p>Note that for APR/native on Windows, the configured value will be reduced to the highest multiple of 1024 that is less than or equal to - maxConnections. This is done for performance reasons.</p> + maxConnections. This is done for performance reasons.<br/> + If set to a value of -1, the maxConnections feature is disabled + and connections are not counted.</p> </attribute> <attribute name="maxThreads" required="false"> Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml?rev=1333116&r1=1333115&r2=1333116&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/config/http.xml Wed May 2 17:15:46 2012 @@ -384,7 +384,9 @@ For APR/native, the default is <code>8192</code>.</p> <p>Note that for APR/native on Windows, the configured value will be reduced to the highest multiple of 1024 that is less than or equal to - maxConnections. This is done for performance reasons.</p> + maxConnections. This is done for performance reasons.<br/> + If set to a value of -1, the maxConnections feature is disabled + and connections are not counted.</p> </attribute> <attribute name="maxHttpHeaderSize" required="false"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org