Author: remm Date: Mon Apr 16 18:50:35 2007 New Revision: 529465 URL: http://svn.apache.org/viewvc?view=rev&rev=529465 Log: - Merge changes to the other protocols, to fix leaking when using an executor (for java.io, not using a thread local has no performance impact). - Harmonize properties between the 4 protocols.
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpProtocol.java tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java?view=diff&rev=529465&r1=529464&r2=529465 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java Mon Apr 16 18:50:35 2007 @@ -21,7 +21,9 @@ import java.net.URLEncoder; import java.util.Hashtable; import java.util.Iterator; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; import javax.management.MBeanRegistration; import javax.management.MBeanServer; @@ -86,7 +88,7 @@ /** * Associated APR endpoint. */ - protected AprEndpoint ep = new AprEndpoint(); + protected AprEndpoint endpoint = new AprEndpoint(); /** @@ -96,25 +98,6 @@ /** - * Should authentication be done in the native webserver layer, - * or in the Servlet container ? - */ - protected boolean tomcatAuthentication = true; - - - /** - * Required secret. - */ - protected String requiredSecret = null; - - - /** - * AJP packet size. - */ - protected int packetSize = Constants.MAX_PACKET_SIZE; - - - /** * Adapter which will process the requests recieved by this endpoint. */ private Adapter adapter; @@ -184,12 +167,12 @@ /** Start the protocol */ public void init() throws Exception { - ep.setName(getName()); - ep.setHandler(cHandler); - ep.setUseSendfile(false); + endpoint.setName(getName()); + endpoint.setHandler(cHandler); + endpoint.setUseSendfile(false); try { - ep.init(); + endpoint.init(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.initerror"), ex); throw ex; @@ -206,7 +189,7 @@ tpOname = new ObjectName (domain + ":" + "type=ThreadPool,name=" + getName()); Registry.getRegistry(null, null) - .registerComponent(ep, tpOname, null ); + .registerComponent(endpoint, tpOname, null ); } catch (Exception e) { log.error("Can't register threadpool" ); } @@ -217,7 +200,7 @@ } try { - ep.start(); + endpoint.start(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.starterror"), ex); throw ex; @@ -228,7 +211,7 @@ public void pause() throws Exception { try { - ep.pause(); + endpoint.pause(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.pauseerror"), ex); throw ex; @@ -239,7 +222,7 @@ public void resume() throws Exception { try { - ep.resume(); + endpoint.resume(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.resumeerror"), ex); throw ex; @@ -251,86 +234,14 @@ public void destroy() throws Exception { if (log.isInfoEnabled()) log.info(sm.getString("ajpprotocol.stop", getName())); - ep.destroy(); + endpoint.destroy(); if (tpOname!=null) Registry.getRegistry(null, null).unregisterComponent(tpOname); if (rgOname != null) Registry.getRegistry(null, null).unregisterComponent(rgOname); } - - // * - public Executor getExecutor() { - return ep.getExecutor(); - } - // * - public void setExecutor(Executor executor) { - ep.setExecutor(executor); - } - - public int getMaxThreads() { - return ep.getMaxThreads(); - } - - public void setMaxThreads(int maxThreads) { - ep.setMaxThreads(maxThreads); - setAttribute("maxThreads", "" + maxThreads); - } - - public void setThreadPriority(int threadPriority) { - ep.setThreadPriority(threadPriority); - setAttribute("threadPriority", "" + threadPriority); - } - - public int getThreadPriority() { - return ep.getThreadPriority(); - } - - - public int getBacklog() { - return ep.getBacklog(); - } - - - public void setBacklog( int i ) { - ep.setBacklog(i); - setAttribute("backlog", "" + i); - } - - - public int getPort() { - return ep.getPort(); - } - - - public void setPort( int port ) { - ep.setPort(port); - setAttribute("port", "" + port); - } - - - public boolean getUseSendfile() { - return ep.getUseSendfile(); - } - - - public void setUseSendfile(boolean useSendfile) { - // No sendfile for AJP - } - - - public InetAddress getAddress() { - return ep.getAddress(); - } - - - public void setAddress(InetAddress ia) { - ep.setAddress(ia); - setAttribute("address", "" + ia); - } - - public String getName() { String encodedAddr = ""; if (getAddress() != null) { @@ -339,108 +250,124 @@ encodedAddr = encodedAddr.substring(1); encodedAddr = URLEncoder.encode(encodedAddr) + "-"; } - return ("ajp-" + encodedAddr + ep.getPort()); - } - - - public boolean getTcpNoDelay() { - return ep.getTcpNoDelay(); - } - - - public void setTcpNoDelay(boolean b) { - ep.setTcpNoDelay(b); - setAttribute("tcpNoDelay", "" + b); - } - - - public boolean getTomcatAuthentication() { - return tomcatAuthentication; - } - - - public void setTomcatAuthentication(boolean tomcatAuthentication) { - this.tomcatAuthentication = tomcatAuthentication; - } - - - public int getPollTime() { - return ep.getPollTime(); - } - - - public void setPollTime(int i) { - ep.setPollTime(i); - setAttribute("pollTime", "" + i); - } - - - public void setPollerSize(int i) { - ep.setPollerSize(i); - setAttribute("pollerSize", "" + i); + return ("ajp-" + encodedAddr + endpoint.getPort()); } + /** + * Processor cache. + */ + protected int processorCache = -1; + public int getProcessorCache() { return this.processorCache; } + public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } - public int getPollerSize() { - return ep.getPollerSize(); - } + public Executor getExecutor() { return endpoint.getExecutor(); } + public void setExecutor(Executor executor) { endpoint.setExecutor(executor); } + + public int getMaxThreads() { return endpoint.getMaxThreads(); } + public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); } + public int getThreadPriority() { return endpoint.getThreadPriority(); } + public void setThreadPriority(int threadPriority) { endpoint.setThreadPriority(threadPriority); } - public int getSoLinger() { - return ep.getSoLinger(); - } + public int getBacklog() { return endpoint.getBacklog(); } + public void setBacklog(int backlog) { endpoint.setBacklog(backlog); } + public int getPort() { return endpoint.getPort(); } + public void setPort(int port) { endpoint.setPort(port); } - public void setSoLinger(int i) { - ep.setSoLinger(i); - setAttribute("soLinger", "" + i); - } + public InetAddress getAddress() { return endpoint.getAddress(); } + public void setAddress(InetAddress ia) { endpoint.setAddress(ia); } + public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); } + public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay); } - public int getSoTimeout() { - return ep.getSoTimeout(); - } + public int getSoLinger() { return endpoint.getSoLinger(); } + public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); } + public int getSoTimeout() { return endpoint.getSoTimeout(); } + public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); } - public void setSoTimeout( int i ) { - ep.setSoTimeout(i); - setAttribute("soTimeout", "" + i); - } + /** + * Should authentication be done in the native webserver layer, + * or in the Servlet container ? + */ + protected boolean tomcatAuthentication = true; + public boolean getTomcatAuthentication() { return tomcatAuthentication; } + public void setTomcatAuthentication(boolean tomcatAuthentication) { this.tomcatAuthentication = tomcatAuthentication; } + /** + * Required secret. + */ + protected String requiredSecret = null; + public void setRequiredSecret(String requiredSecret) { this.requiredSecret = requiredSecret; } - public void setRequiredSecret(String requiredSecret) { - this.requiredSecret = requiredSecret; - } - - - public int getPacketSize() { - return packetSize; - } - - - public void setPacketSize(int i) { - packetSize = i; - } + /** + * AJP packet size. + */ + protected int packetSize = Constants.MAX_PACKET_SIZE; + public int getPacketSize() { return packetSize; } + public void setPacketSize(int packetSize) { this.packetSize = packetSize; } - public int getKeepAliveTimeout() { - return ep.getKeepAliveTimeout(); - } + /** + * The number of seconds Tomcat will wait for a subsequent request + * before closing the connection. + */ + public int getKeepAliveTimeout() { return endpoint.getKeepAliveTimeout(); } + public void setKeepAliveTimeout(int timeout) { endpoint.setKeepAliveTimeout(timeout); } + public boolean getUseSendfile() { return endpoint.getUseSendfile(); } + public void setUseSendfile(boolean useSendfile) { /* No sendfile for AJP */ } - public void setKeepAliveTimeout( int i ) { - ep.setKeepAliveTimeout(i); - setAttribute("keepAliveTimeout", "" + i); - } + public int getPollTime() { return endpoint.getPollTime(); } + public void setPollTime(int pollTime) { endpoint.setPollTime(pollTime); } + public void setPollerSize(int pollerSize) { endpoint.setPollerSize(pollerSize); } + public int getPollerSize() { return endpoint.getPollerSize(); } // -------------------------------------- AjpConnectionHandler Inner Class protected static class AjpConnectionHandler implements Handler { + protected AjpAprProtocol proto; - protected static int count = 0; - protected RequestGroupInfo global=new RequestGroupInfo(); - protected ThreadLocal<AjpAprProcessor> localProcessor = new ThreadLocal<AjpAprProcessor>(); + protected AtomicInteger registerCount = new AtomicInteger(0); + protected RequestGroupInfo global = new RequestGroupInfo(); + + protected ConcurrentLinkedQueue<AjpAprProcessor> recycledProcessors = + new ConcurrentLinkedQueue<AjpAprProcessor>() { + protected AtomicInteger size = new AtomicInteger(0); + public boolean offer(AjpAprProcessor processor) { + boolean offer = (proto.processorCache == -1) ? true : (size.get() < proto.processorCache); + //avoid over growing our cache or add after we have stopped + boolean result = false; + if ( offer ) { + result = super.offer(processor); + if ( result ) { + size.incrementAndGet(); + } + } + if (!result) unregister(processor); + return result; + } + + public AjpAprProcessor poll() { + AjpAprProcessor result = super.poll(); + if ( result != null ) { + size.decrementAndGet(); + } + return result; + } + + public void clear() { + AjpAprProcessor next = poll(); + while ( next != null ) { + unregister(next); + next = poll(); + } + super.clear(); + size.set(0); + } + }; public AjpConnectionHandler(AjpAprProtocol proto) { this.proto = proto; @@ -452,30 +379,11 @@ } public SocketState process(long socket) { - AjpAprProcessor processor = null; + AjpAprProcessor processor = recycledProcessors.poll(); try { - processor = localProcessor.get(); + if (processor == null) { - processor = new AjpAprProcessor(proto.packetSize, proto.ep); - processor.setAdapter(proto.adapter); - processor.setTomcatAuthentication(proto.tomcatAuthentication); - processor.setRequiredSecret(proto.requiredSecret); - localProcessor.set(processor); - if (proto.getDomain() != null) { - synchronized (this) { - try { - RequestInfo rp = processor.getRequest().getRequestProcessor(); - rp.setGlobalProcessor(global); - ObjectName rpName = new ObjectName - (proto.getDomain() + ":type=RequestProcessor,worker=" - + proto.getName() + ",name=AjpRequest" + count++ ); - Registry.getRegistry(null, null) - .registerComponent(rp, rpName, null); - } catch (Exception ex) { - log.warn(sm.getString("ajpprotocol.request.register")); - } - } - } + processor = createProcessor(); } if (processor instanceof ActionHook) { @@ -512,9 +420,62 @@ if (processor instanceof ActionHook) { ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); } + recycledProcessors.offer(processor); } return SocketState.CLOSED; } + + protected AjpAprProcessor createProcessor() { + AjpAprProcessor processor = new AjpAprProcessor(proto.packetSize, proto.endpoint); + processor.setAdapter(proto.adapter); + processor.setTomcatAuthentication(proto.tomcatAuthentication); + processor.setRequiredSecret(proto.requiredSecret); + register(processor); + return processor; + } + + protected void register(AjpAprProcessor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.incrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Register ["+processor+"] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(global); + ObjectName rpName = new ObjectName + (proto.getDomain() + ":type=RequestProcessor,worker=" + + proto.getName() + ",name=AjpRequest" + count); + Registry.getRegistry(null, null).registerComponent(rp, rpName, null); + rp.setRpName(rpName); + } catch (Exception e) { + log.warn("Error registering request"); + } + } + } + } + + protected void unregister(AjpAprProcessor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.decrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Unregister [" + processor + "] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(null); + ObjectName rpName = rp.getRpName(); + Registry.getRegistry(null, null).unregisterComponent(rpName); + rp.setRpName(null); + } catch (Exception e) { + log.warn("Error unregistering request", e); + } + } + } + } + } Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpProtocol.java?view=diff&rev=529465&r1=529464&r2=529465 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpProtocol.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/ajp/AjpProtocol.java Mon Apr 16 18:50:35 2007 @@ -22,7 +22,9 @@ import java.net.URLEncoder; import java.util.Hashtable; import java.util.Iterator; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; import javax.management.MBeanRegistration; import javax.management.MBeanServer; @@ -86,7 +88,7 @@ /** * Associated java.io endpoint. */ - protected JIoEndpoint ep = new JIoEndpoint(); + protected JIoEndpoint endpoint = new JIoEndpoint(); /** @@ -96,25 +98,6 @@ /** - * Should authentication be done in the native webserver layer, - * or in the Servlet container ? - */ - protected boolean tomcatAuthentication = true; - - - /** - * Required secret. - */ - protected String requiredSecret = null; - - - /** - * AJP packet size. - */ - protected int packetSize = Constants.MAX_PACKET_SIZE; - - - /** * Adapter which will process the requests recieved by this endpoint. */ private Adapter adapter; @@ -184,11 +167,11 @@ /** Start the protocol */ public void init() throws Exception { - ep.setName(getName()); - ep.setHandler(cHandler); + endpoint.setName(getName()); + endpoint.setHandler(cHandler); try { - ep.init(); + endpoint.init(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.initerror"), ex); throw ex; @@ -205,7 +188,7 @@ tpOname = new ObjectName (domain + ":" + "type=ThreadPool,name=" + getName()); Registry.getRegistry(null, null) - .registerComponent(ep, tpOname, null ); + .registerComponent(endpoint, tpOname, null ); } catch (Exception e) { log.error("Can't register threadpool" ); } @@ -216,7 +199,7 @@ } try { - ep.start(); + endpoint.start(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.starterror"), ex); throw ex; @@ -227,7 +210,7 @@ public void pause() throws Exception { try { - ep.pause(); + endpoint.pause(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.pauseerror"), ex); throw ex; @@ -238,7 +221,7 @@ public void resume() throws Exception { try { - ep.resume(); + endpoint.resume(); } catch (Exception ex) { log.error(sm.getString("ajpprotocol.endpoint.resumeerror"), ex); throw ex; @@ -250,7 +233,7 @@ public void destroy() throws Exception { if (log.isInfoEnabled()) log.info(sm.getString("ajpprotocol.stop", getName())); - ep.destroy(); + endpoint.destroy(); if (tpOname!=null) Registry.getRegistry(null, null).unregisterComponent(tpOname); if (rgOname != null) @@ -258,67 +241,6 @@ } // * - public Executor getExecutor() { - return ep.getExecutor(); - } - - // * - public void setExecutor(Executor executor) { - ep.setExecutor(executor); - } - - public int getMaxThreads() { - return ep.getMaxThreads(); - } - - public void setMaxThreads(int maxThreads) { - ep.setMaxThreads(maxThreads); - setAttribute("maxThreads", "" + maxThreads); - } - - public void setThreadPriority(int threadPriority) { - ep.setThreadPriority(threadPriority); - setAttribute("threadPriority", "" + threadPriority); - } - - public int getThreadPriority() { - return ep.getThreadPriority(); - } - - - public int getBacklog() { - return ep.getBacklog(); - } - - - public void setBacklog( int i ) { - ep.setBacklog(i); - setAttribute("backlog", "" + i); - } - - - public int getPort() { - return ep.getPort(); - } - - - public void setPort( int port ) { - ep.setPort(port); - setAttribute("port", "" + port); - } - - - public InetAddress getAddress() { - return ep.getAddress(); - } - - - public void setAddress(InetAddress ia) { - ep.setAddress(ia); - setAttribute("address", "" + ia); - } - - public String getName() { String encodedAddr = ""; if (getAddress() != null) { @@ -327,72 +249,68 @@ encodedAddr = encodedAddr.substring(1); encodedAddr = URLEncoder.encode(encodedAddr) + "-"; } - return ("ajp-" + encodedAddr + ep.getPort()); - } - - - public boolean getTcpNoDelay() { - return ep.getTcpNoDelay(); - } - - - public void setTcpNoDelay(boolean b) { - ep.setTcpNoDelay(b); - setAttribute("tcpNoDelay", "" + b); - } - - - public boolean getTomcatAuthentication() { - return tomcatAuthentication; + return ("ajp-" + encodedAddr + endpoint.getPort()); } + /** + * Processor cache. + */ + protected int processorCache = -1; + public int getProcessorCache() { return this.processorCache; } + public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } - public void setTomcatAuthentication(boolean tomcatAuthentication) { - this.tomcatAuthentication = tomcatAuthentication; - } + public Executor getExecutor() { return endpoint.getExecutor(); } + public void setExecutor(Executor executor) { endpoint.setExecutor(executor); } + + public int getMaxThreads() { return endpoint.getMaxThreads(); } + public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); } + public int getThreadPriority() { return endpoint.getThreadPriority(); } + public void setThreadPriority(int threadPriority) { endpoint.setThreadPriority(threadPriority); } - public int getSoLinger() { - return ep.getSoLinger(); - } + public int getBacklog() { return endpoint.getBacklog(); } + public void setBacklog(int backlog) { endpoint.setBacklog(backlog); } + public int getPort() { return endpoint.getPort(); } + public void setPort(int port) { endpoint.setPort(port); } - public void setSoLinger(int i) { - ep.setSoLinger(i); - setAttribute("soLinger", "" + i); - } + public InetAddress getAddress() { return endpoint.getAddress(); } + public void setAddress(InetAddress ia) { endpoint.setAddress(ia); } + public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); } + public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay); } - public int getSoTimeout() { - return ep.getSoTimeout(); - } + public int getSoLinger() { return endpoint.getSoLinger(); } + public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); } + public int getSoTimeout() { return endpoint.getSoTimeout(); } + public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); } - public void setSoTimeout( int i ) { - ep.setSoTimeout(i); - setAttribute("soTimeout", "" + i); - } + /** + * Should authentication be done in the native webserver layer, + * or in the Servlet container ? + */ + protected boolean tomcatAuthentication = true; + public boolean getTomcatAuthentication() { return tomcatAuthentication; } + public void setTomcatAuthentication(boolean tomcatAuthentication) { this.tomcatAuthentication = tomcatAuthentication; } + /** + * Required secret. + */ + protected String requiredSecret = null; + public void setRequiredSecret(String requiredSecret) { this.requiredSecret = requiredSecret; } - public void setRequiredSecret(String requiredSecret) { - this.requiredSecret = requiredSecret; - } - - - public int getPacketSize() { - return packetSize; - } - - - public void setPacketSize(int i) { - packetSize = i; - } + /** + * AJP packet size. + */ + protected int packetSize = Constants.MAX_PACKET_SIZE; + public int getPacketSize() { return packetSize; } + public void setPacketSize(int packetSize) { this.packetSize = packetSize; } /** * The number of seconds Tomcat will wait for a subsequent request - * before closing the connection. The default is the same as for - * Apache HTTP Server (15 000 milliseconds). + * before closing the connection. */ protected int keepAliveTimeout = -1; public int getKeepAliveTimeout() { return keepAliveTimeout; } @@ -403,41 +321,57 @@ protected static class AjpConnectionHandler implements Handler { + protected AjpProtocol proto; - protected static int count = 0; - protected RequestGroupInfo global=new RequestGroupInfo(); - protected ThreadLocal<AjpProcessor> localProcessor = new ThreadLocal<AjpProcessor>(); + protected AtomicInteger registerCount = new AtomicInteger(0); + protected RequestGroupInfo global = new RequestGroupInfo(); + + protected ConcurrentLinkedQueue<AjpProcessor> recycledProcessors = + new ConcurrentLinkedQueue<AjpProcessor>() { + protected AtomicInteger size = new AtomicInteger(0); + public boolean offer(AjpProcessor processor) { + boolean offer = (proto.processorCache == -1) ? true : (size.get() < proto.processorCache); + //avoid over growing our cache or add after we have stopped + boolean result = false; + if ( offer ) { + result = super.offer(processor); + if ( result ) { + size.incrementAndGet(); + } + } + if (!result) unregister(processor); + return result; + } + + public AjpProcessor poll() { + AjpProcessor result = super.poll(); + if ( result != null ) { + size.decrementAndGet(); + } + return result; + } + + public void clear() { + AjpProcessor next = poll(); + while ( next != null ) { + unregister(next); + next = poll(); + } + super.clear(); + size.set(0); + } + }; public AjpConnectionHandler(AjpProtocol proto) { this.proto = proto; } public boolean process(Socket socket) { - AjpProcessor processor = null; + AjpProcessor processor = recycledProcessors.poll(); try { - processor = localProcessor.get(); + if (processor == null) { - processor = new AjpProcessor(proto.packetSize, proto.ep); - processor.setAdapter(proto.adapter); - processor.setTomcatAuthentication(proto.tomcatAuthentication); - processor.setRequiredSecret(proto.requiredSecret); - processor.setKeepAliveTimeout(proto.keepAliveTimeout); - localProcessor.set(processor); - if (proto.getDomain() != null) { - synchronized (this) { - try { - RequestInfo rp = processor.getRequest().getRequestProcessor(); - rp.setGlobalProcessor(global); - ObjectName rpName = new ObjectName - (proto.getDomain() + ":type=RequestProcessor,worker=" - + proto.getName() + ",name=AjpRequest" + count++ ); - Registry.getRegistry(null, null) - .registerComponent(rp, rpName, null); - } catch (Exception ex) { - log.warn(sm.getString("ajpprotocol.request.register")); - } - } - } + processor = createProcessor(); } if (processor instanceof ActionHook) { @@ -470,9 +404,63 @@ if (processor instanceof ActionHook) { ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); } + recycledProcessors.offer(processor); } return false; } + + protected AjpProcessor createProcessor() { + AjpProcessor processor = new AjpProcessor(proto.packetSize, proto.endpoint); + processor.setAdapter(proto.adapter); + processor.setTomcatAuthentication(proto.tomcatAuthentication); + processor.setRequiredSecret(proto.requiredSecret); + processor.setKeepAliveTimeout(proto.keepAliveTimeout); + register(processor); + return processor; + } + + protected void register(AjpProcessor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.incrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Register ["+processor+"] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(global); + ObjectName rpName = new ObjectName + (proto.getDomain() + ":type=RequestProcessor,worker=" + + proto.getName() + ",name=AjpRequest" + count); + Registry.getRegistry(null, null).registerComponent(rp, rpName, null); + rp.setRpName(rpName); + } catch (Exception e) { + log.warn("Error registering request"); + } + } + } + } + + protected void unregister(AjpProcessor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.decrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Unregister [" + processor + "] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(null); + ObjectName rpName = rp.getRpName(); + Registry.getRegistry(null, null).unregisterComponent(rpName); + rp.setRpName(null); + } catch (Exception e) { + log.warn("Error unregistering request", e); + } + } + } + } + } Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?view=diff&rev=529465&r1=529464&r2=529465 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Mon Apr 16 18:50:35 2007 @@ -189,131 +189,76 @@ Registry.getRegistry(null, null).unregisterComponent(rgOname); } - // -------------------- Properties-------------------- + public String getName() { + String encodedAddr = ""; + if (getAddress() != null) { + encodedAddr = "" + getAddress(); + if (encodedAddr.startsWith("/")) + encodedAddr = encodedAddr.substring(1); + encodedAddr = URLEncoder.encode(encodedAddr) + "-"; + } + return ("http-" + encodedAddr + endpoint.getPort()); + } + protected AprEndpoint endpoint=new AprEndpoint(); protected HashMap<String, Object> attributes = new HashMap<String, Object>(); private Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this); - // -------------------- Tcp setup -------------------- + /** + * Processor cache. + */ + protected int processorCache = -1; + public int getProcessorCache() { return this.processorCache; } + public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } - // * - public Executor getExecutor() { - return endpoint.getExecutor(); - } - - // * - public void setExecutor(Executor executor) { - endpoint.setExecutor(executor); - } + public Executor getExecutor() { return endpoint.getExecutor(); } + public void setExecutor(Executor executor) { endpoint.setExecutor(executor); } - // * - public int getMaxThreads() { - return endpoint.getMaxThreads(); - } + public int getMaxThreads() { return endpoint.getMaxThreads(); } + public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); } - // * - public void setMaxThreads( int maxThreads ) { - endpoint.setMaxThreads(maxThreads); - } + public int getThreadPriority() { return endpoint.getThreadPriority(); } + public void setThreadPriority(int threadPriority) { endpoint.setThreadPriority(threadPriority); } - // * - public void setThreadPriority(int threadPriority) { - endpoint.setThreadPriority(threadPriority); - } + public int getBacklog() { return endpoint.getBacklog(); } + public void setBacklog(int backlog) { endpoint.setBacklog(backlog); } - // * - public int getThreadPriority() { - return endpoint.getThreadPriority(); - } + public int getPort() { return endpoint.getPort(); } + public void setPort(int port) { endpoint.setPort(port); } - // * - public int getBacklog() { - return endpoint.getBacklog(); - } + public InetAddress getAddress() { return endpoint.getAddress(); } + public void setAddress(InetAddress ia) { endpoint.setAddress(ia); } - // * - public void setBacklog( int i ) { - endpoint.setBacklog(i); - } + public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); } + public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay); } - // * - public int getPort() { - return endpoint.getPort(); - } + public int getSoLinger() { return endpoint.getSoLinger(); } + public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); } - // * - public void setPort( int port ) { - endpoint.setPort(port); - } + public int getSoTimeout() { return endpoint.getSoTimeout(); } + public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); } - // * - public InetAddress getAddress() { - return endpoint.getAddress(); - } + /** + * The number of seconds Tomcat will wait for a subsequent request + * before closing the connection. + */ + public int getKeepAliveTimeout() { return endpoint.getKeepAliveTimeout(); } + public void setKeepAliveTimeout(int timeout) { endpoint.setKeepAliveTimeout(timeout); } - // * - public void setAddress(InetAddress ia) { - endpoint.setAddress( ia ); - } + public boolean getUseSendfile() { return endpoint.getUseSendfile(); } + public void setUseSendfile(boolean useSendfile) { endpoint.setUseSendfile(useSendfile); } - public int getPollTime() { - return endpoint.getPollTime(); - } + public int getPollTime() { return endpoint.getPollTime(); } + public void setPollTime(int pollTime) { endpoint.setPollTime(pollTime); } - public void setPollTime( int i ) { - endpoint.setPollTime(i); - setAttribute("pollTime", "" + i); - } + public void setPollerSize(int pollerSize) { endpoint.setPollerSize(pollerSize); } + public int getPollerSize() { return endpoint.getPollerSize(); } - public void setPollerSize(int i) { - endpoint.setPollerSize(i); - setAttribute("pollerSize", "" + i); - } - - public int getPollerSize() { - return endpoint.getPollerSize(); - } - - public void setSendfileSize(int i) { - endpoint.setSendfileSize(i); - setAttribute("sendfileSize", "" + i); - } + public int getSendfileSize() { return endpoint.getSendfileSize(); } + public void setSendfileSize(int sendfileSize) { endpoint.setSendfileSize(sendfileSize); } - public int getSendfileSize() { - return endpoint.getSendfileSize(); - } - - public boolean getUseSendfile() { - return endpoint.getUseSendfile(); - } - - public void setUseSendfile(boolean useSendfile) { - endpoint.setUseSendfile(useSendfile); - } - - public String getName() { - String encodedAddr = ""; - if (getAddress() != null) { - encodedAddr = "" + getAddress(); - if (encodedAddr.startsWith("/")) - encodedAddr = encodedAddr.substring(1); - encodedAddr = URLEncoder.encode(encodedAddr) + "-"; - } - return ("http-" + encodedAddr + endpoint.getPort()); - } - - // * - public boolean getTcpNoDelay() { - return endpoint.getTcpNoDelay(); - } - - // * - public void setTcpNoDelay( boolean b ) { - endpoint.setTcpNoDelay( b ); - } - protected int socketBuffer = 9000; public int getSocketBuffer() { return socketBuffer; } public void setSocketBuffer(int socketBuffer) { this.socketBuffer = socketBuffer; } @@ -380,26 +325,6 @@ public void setRestrictedUserAgents(String valueS) { restrictedUserAgents = valueS; } - // * - public int getSoLinger() { - return endpoint.getSoLinger(); - } - - // * - public void setSoLinger( int i ) { - endpoint.setSoLinger( i ); - } - - // * - public int getSoTimeout() { - return endpoint.getSoTimeout(); - } - - // * - public void setSoTimeout( int i ) { - endpoint.setSoTimeout(i); - } - public String getProtocol() { return getProperty("protocol"); } @@ -418,13 +343,6 @@ public void setMaxKeepAliveRequests(int mkar) { maxKeepAliveRequests = mkar; } /** - * The number of seconds Tomcat will wait for a subsequent request - * before closing the connection. - */ - public int getKeepAliveTimeout() { return endpoint.getKeepAliveTimeout(); } - public void setKeepAliveTimeout(int timeout) { endpoint.setKeepAliveTimeout(timeout); } - - /** * Return the Keep-Alive policy for the connection. */ public boolean getKeepAlive() { @@ -458,13 +376,6 @@ public void setTimeout(int timeout) { this.timeout = timeout; } /** - * Processor cache. - */ - protected int processorCache = -1; - public int getProcessorCache() { return this.processorCache; } - public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } - - /** * This field indicates if the protocol is secure from the perspective of * the client (= https is used). */ @@ -579,7 +490,7 @@ new ConcurrentLinkedQueue<Http11AprProcessor>() { protected AtomicInteger size = new AtomicInteger(0); public boolean offer(Http11AprProcessor processor) { - boolean offer = proto.processorCache==-1?true:size.get() < proto.processorCache; + boolean offer = (proto.processorCache == -1) ? true : (size.get() < proto.processorCache); //avoid over growing our cache or add after we have stopped boolean result = false; if ( offer ) { Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java?view=diff&rev=529465&r1=529464&r2=529465 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java Mon Apr 16 18:50:35 2007 @@ -22,7 +22,9 @@ import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; import javax.management.MBeanRegistration; import javax.management.MBeanServer; @@ -49,7 +51,6 @@ * * @author Remy Maucherat * @author Costin Manolache - * @deprecated */ public class Http11Protocol implements ProtocolHandler, MBeanRegistration { @@ -240,10 +241,27 @@ Registry.getRegistry(null, null).unregisterComponent(rgOname); } - + public String getName() { + String encodedAddr = ""; + if (getAddress() != null) { + encodedAddr = "" + getAddress(); + if (encodedAddr.startsWith("/")) + encodedAddr = encodedAddr.substring(1); + encodedAddr = URLEncoder.encode(encodedAddr) + "-"; + } + return ("http-" + encodedAddr + endpoint.getPort()); + } + // ------------------------------------------------------------- Properties + /** + * Processor cache. + */ + protected int processorCache = -1; + public int getProcessorCache() { return this.processorCache; } + public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } + // * /** * This field indicates if the protocol is secure from the perspective of @@ -264,7 +282,6 @@ public String getSocketFactory() { return socketFactoryName; } public void setSocketFactory(String valueS) { socketFactoryName = valueS; } - /** * Name of the SSL implementation. */ @@ -371,7 +388,6 @@ public String getRestrictedUserAgents() { return restrictedUserAgents; } public void setRestrictedUserAgents(String valueS) { restrictedUserAgents = valueS; } - // HTTP /** * Server header. @@ -380,110 +396,32 @@ public void setServer( String server ) { this.server = server; } public String getServer() { return server; } - - // --------------------------------------------------------- Public methods - - // * - public Executor getExecutor() { - return endpoint.getExecutor(); - } - - // * - public void setExecutor(Executor executor) { - endpoint.setExecutor(executor); - } + public Executor getExecutor() { return endpoint.getExecutor(); } + public void setExecutor(Executor executor) { endpoint.setExecutor(executor); } - // * - public int getMaxThreads() { - return endpoint.getMaxThreads(); - } + public int getMaxThreads() { return endpoint.getMaxThreads(); } + public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); } - // * - public void setMaxThreads( int maxThreads ) { - endpoint.setMaxThreads(maxThreads); - } + public int getThreadPriority() { return endpoint.getThreadPriority(); } + public void setThreadPriority(int threadPriority) { endpoint.setThreadPriority(threadPriority); } - // * - public void setThreadPriority(int threadPriority) { - endpoint.setThreadPriority(threadPriority); - } + public int getBacklog() { return endpoint.getBacklog(); } + public void setBacklog(int backlog) { endpoint.setBacklog(backlog); } - // * - public int getThreadPriority() { - return endpoint.getThreadPriority(); - } + public int getPort() { return endpoint.getPort(); } + public void setPort(int port) { endpoint.setPort(port); } - // * - public int getBacklog() { - return endpoint.getBacklog(); - } - - // * - public void setBacklog( int i ) { - endpoint.setBacklog(i); - } - - // * - public int getPort() { - return endpoint.getPort(); - } + public InetAddress getAddress() { return endpoint.getAddress(); } + public void setAddress(InetAddress ia) { endpoint.setAddress(ia); } - // * - public void setPort( int port ) { - endpoint.setPort(port); - } + public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); } + public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay); } - // * - public InetAddress getAddress() { - return endpoint.getAddress(); - } + public int getSoLinger() { return endpoint.getSoLinger(); } + public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); } - // * - public void setAddress(InetAddress ia) { - endpoint.setAddress( ia ); - } - - // * - public String getName() { - String encodedAddr = ""; - if (getAddress() != null) { - encodedAddr = "" + getAddress(); - if (encodedAddr.startsWith("/")) - encodedAddr = encodedAddr.substring(1); - encodedAddr = URLEncoder.encode(encodedAddr) + "-"; - } - return ("http-" + encodedAddr + endpoint.getPort()); - } - - // * - public boolean getTcpNoDelay() { - return endpoint.getTcpNoDelay(); - } - - // * - public void setTcpNoDelay( boolean b ) { - endpoint.setTcpNoDelay( b ); - } - - // * - public int getSoLinger() { - return endpoint.getSoLinger(); - } - - // * - public void setSoLinger( int i ) { - endpoint.setSoLinger( i ); - } - - // * - public int getSoTimeout() { - return endpoint.getSoTimeout(); - } - - // * - public void setSoTimeout( int i ) { - endpoint.setSoTimeout(i); - } + public int getSoTimeout() { return endpoint.getSoTimeout(); } + public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); } // HTTP /** @@ -575,58 +513,66 @@ // ----------------------------------- Http11ConnectionHandler Inner Class protected static class Http11ConnectionHandler implements Handler { - protected Http11Protocol protocol; - protected static int count = 0; + + protected Http11Protocol proto; + protected AtomicInteger registerCount = new AtomicInteger(0); protected RequestGroupInfo global = new RequestGroupInfo(); - protected ThreadLocal<Http11Processor> localProcessor = new ThreadLocal<Http11Processor>(); + + protected ConcurrentLinkedQueue<Http11Processor> recycledProcessors = + new ConcurrentLinkedQueue<Http11Processor>() { + protected AtomicInteger size = new AtomicInteger(0); + public boolean offer(Http11Processor processor) { + boolean offer = (proto.processorCache == -1) ? true : (size.get() < proto.processorCache); + //avoid over growing our cache or add after we have stopped + boolean result = false; + if ( offer ) { + result = super.offer(processor); + if ( result ) { + size.incrementAndGet(); + } + } + if (!result) unregister(processor); + return result; + } + + public Http11Processor poll() { + Http11Processor result = super.poll(); + if ( result != null ) { + size.decrementAndGet(); + } + return result; + } + + public void clear() { + Http11Processor next = poll(); + while ( next != null ) { + unregister(next); + next = poll(); + } + super.clear(); + size.set(0); + } + }; Http11ConnectionHandler(Http11Protocol proto) { - this.protocol = proto; + this.proto = proto; } public boolean process(Socket socket) { - Http11Processor processor = null; + Http11Processor processor = recycledProcessors.poll(); try { - processor = localProcessor.get(); + if (processor == null) { - processor = - new Http11Processor(protocol.maxHttpHeaderSize, protocol.endpoint); - processor.setAdapter(protocol.adapter); - processor.setMaxKeepAliveRequests(protocol.maxKeepAliveRequests); - processor.setKeepAliveTimeout(protocol.keepAliveTimeout); - processor.setTimeout(protocol.timeout); - processor.setDisableUploadTimeout(protocol.disableUploadTimeout); - processor.setCompression(protocol.compression); - processor.setCompressionMinSize(protocol.compressionMinSize); - processor.setNoCompressionUserAgents(protocol.noCompressionUserAgents); - processor.setCompressableMimeTypes(protocol.compressableMimeTypes); - processor.setRestrictedUserAgents(protocol.restrictedUserAgents); - processor.setMaxSavePostSize(protocol.maxSavePostSize); - processor.setServer(protocol.server); - localProcessor.set(processor); - if (protocol.getDomain() != null) { - synchronized (this) { - try { - RequestInfo rp = processor.getRequest().getRequestProcessor(); - rp.setGlobalProcessor(global); - ObjectName rpName = new ObjectName - (protocol.getDomain() + ":type=RequestProcessor,worker=" - + protocol.getName() + ",name=HttpRequest" + count++); - Registry.getRegistry(null, null).registerComponent(rp, rpName, null); - } catch (Exception e) { - log.warn("Error registering request"); - } - } - } + processor = createProcessor(); } if (processor instanceof ActionHook) { ((ActionHook) processor).action(ActionCode.ACTION_START, null); } - if (protocol.secure && (protocol.sslImplementation != null)) { + if (proto.secure && (proto.sslImplementation != null)) { processor.setSSLSupport - (protocol.sslImplementation.getSSLSupport(socket)); + (proto.sslImplementation.getSSLSupport(socket)); } else { processor.setSSLSupport(null); } @@ -661,9 +607,72 @@ if (processor instanceof ActionHook) { ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); } + recycledProcessors.offer(processor); } return false; } + + protected Http11Processor createProcessor() { + Http11Processor processor = + new Http11Processor(proto.maxHttpHeaderSize, proto.endpoint); + processor.setAdapter(proto.adapter); + processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests); + processor.setKeepAliveTimeout(proto.keepAliveTimeout); + processor.setTimeout(proto.timeout); + processor.setDisableUploadTimeout(proto.disableUploadTimeout); + processor.setCompression(proto.compression); + processor.setCompressionMinSize(proto.compressionMinSize); + processor.setNoCompressionUserAgents(proto.noCompressionUserAgents); + processor.setCompressableMimeTypes(proto.compressableMimeTypes); + processor.setRestrictedUserAgents(proto.restrictedUserAgents); + processor.setMaxSavePostSize(proto.maxSavePostSize); + processor.setServer(proto.server); + register(processor); + return processor; + } + + protected void register(Http11Processor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.incrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Register ["+processor+"] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(global); + ObjectName rpName = new ObjectName + (proto.getDomain() + ":type=RequestProcessor,worker=" + + proto.getName() + ",name=HttpRequest" + count); + Registry.getRegistry(null, null).registerComponent(rp, rpName, null); + rp.setRpName(rpName); + } catch (Exception e) { + log.warn("Error registering request"); + } + } + } + } + + protected void unregister(Http11Processor processor) { + if (proto.getDomain() != null) { + synchronized (this) { + try { + int count = registerCount.decrementAndGet(); + if (log.isDebugEnabled()) { + log.debug("Unregister [" + processor + "] count=" + count); + } + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(null); + ObjectName rpName = rp.getRpName(); + Registry.getRegistry(null, null).unregisterComponent(rpName); + rp.setRpName(null); + } catch (Exception e) { + log.warn("Error unregistering request", e); + } + } + } + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]