Author: remm Date: Mon Apr 16 09:14:47 2007 New Revision: 529305 URL: http://svn.apache.org/viewvc?view=rev&rev=529305 Log: - Port changes from the NIO connector to the APR connector, to resolve memory leaking when using an executor (note: when not using an executor, no memory leak could occur). - Discard thread local usage altogether, as my testing did not show a measurable performance difference. I don't know if this would change when scaling up the number of CPUs (if anyone wants to test). - No size limit by default, since this is mechanically limited (amount of threads + open comet connections). - Harmonize code with the HTTP/1.1 connector.
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java 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=529305&r1=529304&r2=529305 ============================================================================== --- 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 09:14:47 2007 @@ -19,10 +19,13 @@ import java.net.InetAddress; import java.net.URLEncoder; +import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; +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,15 +52,10 @@ * @author Remy Maucherat * @author Costin Manolache */ -public class Http11AprProtocol implements ProtocolHandler, MBeanRegistration -{ - public Http11AprProtocol() { - cHandler = new Http11ConnectionHandler( this ); - setSoLinger(Constants.DEFAULT_CONNECTION_LINGER); - setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT); - //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT); - setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY); - } +public class Http11AprProtocol implements ProtocolHandler, MBeanRegistration { + + protected static org.apache.juli.logging.Log log = + org.apache.juli.logging.LogFactory.getLog(Http11AprProtocol.class); /** * The string manager for this package. @@ -65,6 +63,13 @@ protected static StringManager sm = StringManager.getManager(Constants.Package); + public Http11AprProtocol() { + setSoLinger(Constants.DEFAULT_CONNECTION_LINGER); + setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT); + //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT); + setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY); + } + /** Pass config info */ public void setAttribute( String name, Object value ) { @@ -98,25 +103,22 @@ return (String)getAttribute(name); } - /** The adapter, used to call the connector + /** + * The adapter, used to call the connector. */ - public void setAdapter(Adapter adapter) { - this.adapter=adapter; - } - - public Adapter getAdapter() { - return adapter; - } + protected Adapter adapter; + public void setAdapter(Adapter adapter) { this.adapter = adapter; } + public Adapter getAdapter() { return adapter; } /** 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("http11protocol.endpoint.initerror"), ex); throw ex; @@ -135,7 +137,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" ); } @@ -146,7 +148,7 @@ } try { - ep.start(); + endpoint.start(); } catch (Exception ex) { log.error(sm.getString("http11protocol.endpoint.starterror"), ex); throw ex; @@ -157,7 +159,7 @@ public void pause() throws Exception { try { - ep.pause(); + endpoint.pause(); } catch (Exception ex) { log.error(sm.getString("http11protocol.endpoint.pauseerror"), ex); throw ex; @@ -168,7 +170,7 @@ public void resume() throws Exception { try { - ep.resume(); + endpoint.resume(); } catch (Exception ex) { log.error(sm.getString("http11protocol.endpoint.resumeerror"), ex); throw ex; @@ -180,7 +182,7 @@ public void destroy() throws Exception { if(log.isInfoEnabled()) log.info(sm.getString("http11protocol.stop", getName())); - ep.destroy(); + endpoint.destroy(); if( tpOname!=null ) Registry.getRegistry(null, null).unregisterComponent(tpOname); if( rgOname != null ) @@ -188,124 +190,107 @@ } // -------------------- Properties-------------------- - protected AprEndpoint ep=new AprEndpoint(); - protected boolean secure; - - protected Hashtable attributes = new Hashtable(); + protected AprEndpoint endpoint=new AprEndpoint(); - private int maxKeepAliveRequests=100; // as in Apache HTTPD server - private int timeout = 300000; // 5 minutes as in Apache HTTPD server - private int maxSavePostSize = 4 * 1024; - private int maxHttpHeaderSize = 8 * 1024; - private int socketCloseDelay=-1; - private boolean disableUploadTimeout = true; - private int socketBuffer = 9000; - private Adapter adapter; - private Http11ConnectionHandler cHandler; - - /** - * Compression value. - */ - private String compression = "off"; - private String noCompressionUserAgents = null; - private String restrictedUserAgents = null; - private String compressableMimeTypes = "text/html,text/xml,text/plain"; - private int compressionMinSize = 2048; + protected HashMap<String, Object> attributes = new HashMap<String, Object>(); - private String server; + private Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this); - // -------------------- Pool setup -------------------- + // -------------------- Tcp setup -------------------- // * public Executor getExecutor() { - return ep.getExecutor(); + return endpoint.getExecutor(); } // * public void setExecutor(Executor executor) { - ep.setExecutor(executor); + endpoint.setExecutor(executor); } + // * public int getMaxThreads() { - return ep.getMaxThreads(); + return endpoint.getMaxThreads(); } + // * public void setMaxThreads( int maxThreads ) { - ep.setMaxThreads(maxThreads); - setAttribute("maxThreads", "" + maxThreads); + endpoint.setMaxThreads(maxThreads); } + // * public void setThreadPriority(int threadPriority) { - ep.setThreadPriority(threadPriority); - setAttribute("threadPriority", "" + threadPriority); + endpoint.setThreadPriority(threadPriority); } + // * public int getThreadPriority() { - return ep.getThreadPriority(); + return endpoint.getThreadPriority(); } - // -------------------- Tcp setup -------------------- - + // * public int getBacklog() { - return ep.getBacklog(); + return endpoint.getBacklog(); } + // * public void setBacklog( int i ) { - ep.setBacklog(i); - setAttribute("backlog", "" + i); + endpoint.setBacklog(i); } + // * public int getPort() { - return ep.getPort(); + return endpoint.getPort(); } + // * public void setPort( int port ) { - ep.setPort(port); - setAttribute("port", "" + port); + endpoint.setPort(port); + } + + // * + public InetAddress getAddress() { + return endpoint.getAddress(); + } + + // * + public void setAddress(InetAddress ia) { + endpoint.setAddress( ia ); } public int getPollTime() { - return ep.getPollTime(); + return endpoint.getPollTime(); } public void setPollTime( int i ) { - ep.setPollTime(i); + endpoint.setPollTime(i); setAttribute("pollTime", "" + i); } public void setPollerSize(int i) { - ep.setPollerSize(i); + endpoint.setPollerSize(i); setAttribute("pollerSize", "" + i); } public int getPollerSize() { - return ep.getPollerSize(); + return endpoint.getPollerSize(); } public void setSendfileSize(int i) { - ep.setSendfileSize(i); + endpoint.setSendfileSize(i); setAttribute("sendfileSize", "" + i); } public int getSendfileSize() { - return ep.getSendfileSize(); + return endpoint.getSendfileSize(); } public boolean getUseSendfile() { - return ep.getUseSendfile(); + return endpoint.getUseSendfile(); } public void setUseSendfile(boolean useSendfile) { - ep.setUseSendfile(useSendfile); - } - - public InetAddress getAddress() { - return ep.getAddress(); - } - - public void setAddress(InetAddress ia) { - ep.setAddress( ia ); - setAttribute("address", "" + ia); + endpoint.setUseSendfile(useSendfile); } public String getName() { @@ -316,113 +301,103 @@ encodedAddr = encodedAddr.substring(1); encodedAddr = URLEncoder.encode(encodedAddr) + "-"; } - return ("http-" + encodedAddr + ep.getPort()); + return ("http-" + encodedAddr + endpoint.getPort()); } + // * public boolean getTcpNoDelay() { - return ep.getTcpNoDelay(); + return endpoint.getTcpNoDelay(); } + // * public void setTcpNoDelay( boolean b ) { - ep.setTcpNoDelay( b ); - setAttribute("tcpNoDelay", "" + b); - } - - public boolean getDisableUploadTimeout() { - return disableUploadTimeout; - } - - public void setDisableUploadTimeout(boolean isDisabled) { - disableUploadTimeout = isDisabled; - } - - public int getSocketBuffer() { - return socketBuffer; - } - - public void setSocketBuffer(int valueI) { - socketBuffer = valueI; - } - - public String getCompression() { - return compression; - } - - public void setCompression(String valueS) { - compression = valueS; - setAttribute("compression", valueS); - } - - public int getMaxSavePostSize() { - return maxSavePostSize; - } - - public void setMaxSavePostSize(int valueI) { - maxSavePostSize = valueI; - setAttribute("maxSavePostSize", "" + valueI); - } - - public int getMaxHttpHeaderSize() { - return maxHttpHeaderSize; + endpoint.setTcpNoDelay( b ); } - public void setMaxHttpHeaderSize(int valueI) { - maxHttpHeaderSize = valueI; - setAttribute("maxHttpHeaderSize", "" + valueI); - } - - public String getRestrictedUserAgents() { - return restrictedUserAgents; - } + protected int socketBuffer = 9000; + public int getSocketBuffer() { return socketBuffer; } + public void setSocketBuffer(int socketBuffer) { this.socketBuffer = socketBuffer; } - public void setRestrictedUserAgents(String valueS) { - restrictedUserAgents = valueS; - setAttribute("restrictedUserAgents", valueS); - } + /** + * Maximum size of the post which will be saved when processing certain + * requests, such as a POST. + */ + protected int maxSavePostSize = 4 * 1024; + public int getMaxSavePostSize() { return maxSavePostSize; } + public void setMaxSavePostSize(int valueI) { maxSavePostSize = valueI; } - public String getNoCompressionUserAgents() { - return noCompressionUserAgents; - } + // HTTP + /** + * Maximum size of the HTTP message header. + */ + protected int maxHttpHeaderSize = 8 * 1024; + public int getMaxHttpHeaderSize() { return maxHttpHeaderSize; } + public void setMaxHttpHeaderSize(int valueI) { maxHttpHeaderSize = valueI; } - public void setNoCompressionUserAgents(String valueS) { - noCompressionUserAgents = valueS; - setAttribute("noCompressionUserAgents", valueS); - } - public String getCompressableMimeType() { - return compressableMimeTypes; - } + // HTTP + /** + * If true, the regular socket timeout will be used for the full duration + * of the connection. + */ + protected boolean disableUploadTimeout = true; + public boolean getDisableUploadTimeout() { return disableUploadTimeout; } + public void setDisableUploadTimeout(boolean isDisabled) { disableUploadTimeout = isDisabled; } - public void setCompressableMimeType(String valueS) { - compressableMimeTypes = valueS; - setAttribute("compressableMimeTypes", valueS); - } + // HTTP + /** + * Integrated compression support. + */ + protected String compression = "off"; + public String getCompression() { return compression; } + public void setCompression(String valueS) { compression = valueS; } + + + // HTTP + protected String noCompressionUserAgents = null; + public String getNoCompressionUserAgents() { return noCompressionUserAgents; } + public void setNoCompressionUserAgents(String valueS) { noCompressionUserAgents = valueS; } - public int getCompressionMinSize() { - return compressionMinSize; - } + + // HTTP + protected String compressableMimeTypes = "text/html,text/xml,text/plain"; + public String getCompressableMimeType() { return compressableMimeTypes; } + public void setCompressableMimeType(String valueS) { compressableMimeTypes = valueS; } + + + // HTTP + protected int compressionMinSize = 2048; + public int getCompressionMinSize() { return compressionMinSize; } + public void setCompressionMinSize(int valueI) { compressionMinSize = valueI; } - public void setCompressionMinSize(int valueI) { - compressionMinSize = valueI; - setAttribute("compressionMinSize", "" + valueI); - } + // HTTP + /** + * User agents regular expressions which should be restricted to HTTP/1.0 support. + */ + protected String restrictedUserAgents = null; + public String getRestrictedUserAgents() { return restrictedUserAgents; } + public void setRestrictedUserAgents(String valueS) { restrictedUserAgents = valueS; } + + + // * public int getSoLinger() { - return ep.getSoLinger(); + return endpoint.getSoLinger(); } + // * public void setSoLinger( int i ) { - ep.setSoLinger( i ); - setAttribute("soLinger", "" + i); + endpoint.setSoLinger( i ); } + // * public int getSoTimeout() { - return ep.getSoTimeout(); + return endpoint.getSoTimeout(); } + // * public void setSoTimeout( int i ) { - ep.setSoTimeout(i); - setAttribute("soTimeout", "" + i); + endpoint.setSoTimeout(i); } public String getProtocol() { @@ -434,39 +409,24 @@ setAttribute("protocol", k); } - public boolean getSecure() { - return secure; - } - - public void setSecure( boolean b ) { - secure=b; - setAttribute("secure", "" + b); - } - - public int getMaxKeepAliveRequests() { - return maxKeepAliveRequests; - } - - /** Set the maximum number of Keep-Alive requests that we will honor. + /** + * Maximum number of requests which can be performed over a keepalive + * connection. The default is the same as for Apache HTTP Server. */ - public void setMaxKeepAliveRequests(int mkar) { - maxKeepAliveRequests = mkar; - setAttribute("maxKeepAliveRequests", "" + mkar); - } + protected int maxKeepAliveRequests = 100; + public int getMaxKeepAliveRequests() { return maxKeepAliveRequests; } + 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 ep.getKeepAliveTimeout(); - } - - public void setKeepAliveTimeout(int timeout) { - ep.setKeepAliveTimeout(timeout); - } + 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() { return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1)); } @@ -480,139 +440,177 @@ } } - public int getSocketCloseDelay() { - return socketCloseDelay; - } - - public void setSocketCloseDelay( int d ) { - socketCloseDelay=d; - setAttribute("socketCloseDelay", "" + d); - } - - public void setServer( String server ) { - this.server = server; - } + /** + * Server header. + */ + protected String server; + public void setServer( String server ) { this.server = server; } + public String getServer() { return server; } - public String getServer() { - return server; - } + /** + * This timeout represents the socket timeout which will be used while + * the adapter execution is in progress, unless disableUploadTimeout + * is set to true. The default is the same as for Apache HTTP Server + * (300 000 milliseconds). + */ + protected int timeout = 300000; + public int getTimeout() { return timeout; } + public void setTimeout(int timeout) { this.timeout = timeout; } - public int getTimeout() { - return timeout; - } + /** + * Processor cache. + */ + protected int processorCache = -1; + public int getProcessorCache() { return this.processorCache; } + public void setProcessorCache(int processorCache) { this.processorCache = processorCache; } - public void setTimeout( int timeouts ) { - timeout = timeouts; - setAttribute("timeout", "" + timeouts); - } + /** + * This field indicates if the protocol is secure from the perspective of + * the client (= https is used). + */ + protected boolean secure; + public boolean getSecure() { return secure; } + public void setSecure(boolean b) { secure = b; } // -------------------- SSL related properties -------------------- /** * SSL engine. */ - public boolean isSSLEnabled() { return ep.isSSLEnabled(); } - public void setSSLEnabled(boolean SSLEnabled) { ep.setSSLEnabled(SSLEnabled); } + public boolean isSSLEnabled() { return endpoint.isSSLEnabled(); } + public void setSSLEnabled(boolean SSLEnabled) { endpoint.setSSLEnabled(SSLEnabled); } /** * SSL protocol. */ - public String getSSLProtocol() { return ep.getSSLProtocol(); } - public void setSSLProtocol(String SSLProtocol) { ep.setSSLProtocol(SSLProtocol); } + public String getSSLProtocol() { return endpoint.getSSLProtocol(); } + public void setSSLProtocol(String SSLProtocol) { endpoint.setSSLProtocol(SSLProtocol); } /** * SSL password (if a cert is encrypted, and no password has been provided, a callback * will ask for a password). */ - public String getSSLPassword() { return ep.getSSLPassword(); } - public void setSSLPassword(String SSLPassword) { ep.setSSLPassword(SSLPassword); } + public String getSSLPassword() { return endpoint.getSSLPassword(); } + public void setSSLPassword(String SSLPassword) { endpoint.setSSLPassword(SSLPassword); } /** * SSL cipher suite. */ - public String getSSLCipherSuite() { return ep.getSSLCipherSuite(); } - public void setSSLCipherSuite(String SSLCipherSuite) { ep.setSSLCipherSuite(SSLCipherSuite); } + public String getSSLCipherSuite() { return endpoint.getSSLCipherSuite(); } + public void setSSLCipherSuite(String SSLCipherSuite) { endpoint.setSSLCipherSuite(SSLCipherSuite); } /** * SSL certificate file. */ - public String getSSLCertificateFile() { return ep.getSSLCertificateFile(); } - public void setSSLCertificateFile(String SSLCertificateFile) { ep.setSSLCertificateFile(SSLCertificateFile); } + public String getSSLCertificateFile() { return endpoint.getSSLCertificateFile(); } + public void setSSLCertificateFile(String SSLCertificateFile) { endpoint.setSSLCertificateFile(SSLCertificateFile); } /** * SSL certificate key file. */ - public String getSSLCertificateKeyFile() { return ep.getSSLCertificateKeyFile(); } - public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { ep.setSSLCertificateKeyFile(SSLCertificateKeyFile); } + public String getSSLCertificateKeyFile() { return endpoint.getSSLCertificateKeyFile(); } + public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { endpoint.setSSLCertificateKeyFile(SSLCertificateKeyFile); } /** * SSL certificate chain file. */ - public String getSSLCertificateChainFile() { return ep.getSSLCertificateChainFile(); } - public void setSSLCertificateChainFile(String SSLCertificateChainFile) { ep.setSSLCertificateChainFile(SSLCertificateChainFile); } + public String getSSLCertificateChainFile() { return endpoint.getSSLCertificateChainFile(); } + public void setSSLCertificateChainFile(String SSLCertificateChainFile) { endpoint.setSSLCertificateChainFile(SSLCertificateChainFile); } /** * SSL CA certificate path. */ - public String getSSLCACertificatePath() { return ep.getSSLCACertificatePath(); } - public void setSSLCACertificatePath(String SSLCACertificatePath) { ep.setSSLCACertificatePath(SSLCACertificatePath); } + public String getSSLCACertificatePath() { return endpoint.getSSLCACertificatePath(); } + public void setSSLCACertificatePath(String SSLCACertificatePath) { endpoint.setSSLCACertificatePath(SSLCACertificatePath); } /** * SSL CA certificate file. */ - public String getSSLCACertificateFile() { return ep.getSSLCACertificateFile(); } - public void setSSLCACertificateFile(String SSLCACertificateFile) { ep.setSSLCACertificateFile(SSLCACertificateFile); } + public String getSSLCACertificateFile() { return endpoint.getSSLCACertificateFile(); } + public void setSSLCACertificateFile(String SSLCACertificateFile) { endpoint.setSSLCACertificateFile(SSLCACertificateFile); } /** * SSL CA revocation path. */ - public String getSSLCARevocationPath() { return ep.getSSLCARevocationPath(); } - public void setSSLCARevocationPath(String SSLCARevocationPath) { ep.setSSLCARevocationPath(SSLCARevocationPath); } + public String getSSLCARevocationPath() { return endpoint.getSSLCARevocationPath(); } + public void setSSLCARevocationPath(String SSLCARevocationPath) { endpoint.setSSLCARevocationPath(SSLCARevocationPath); } /** * SSL CA revocation file. */ - public String getSSLCARevocationFile() { return ep.getSSLCARevocationFile(); } - public void setSSLCARevocationFile(String SSLCARevocationFile) { ep.setSSLCARevocationFile(SSLCARevocationFile); } + public String getSSLCARevocationFile() { return endpoint.getSSLCARevocationFile(); } + public void setSSLCARevocationFile(String SSLCARevocationFile) { endpoint.setSSLCARevocationFile(SSLCARevocationFile); } /** * SSL verify client. */ - public String getSSLVerifyClient() { return ep.getSSLVerifyClient(); } - public void setSSLVerifyClient(String SSLVerifyClient) { ep.setSSLVerifyClient(SSLVerifyClient); } + public String getSSLVerifyClient() { return endpoint.getSSLVerifyClient(); } + public void setSSLVerifyClient(String SSLVerifyClient) { endpoint.setSSLVerifyClient(SSLVerifyClient); } /** * SSL verify depth. */ - public int getSSLVerifyDepth() { return ep.getSSLVerifyDepth(); } - public void setSSLVerifyDepth(int SSLVerifyDepth) { ep.setSSLVerifyDepth(SSLVerifyDepth); } - + public int getSSLVerifyDepth() { return endpoint.getSSLVerifyDepth(); } + public void setSSLVerifyDepth(int SSLVerifyDepth) { endpoint.setSSLVerifyDepth(SSLVerifyDepth); } + // -------------------- Connection handler -------------------- static class Http11ConnectionHandler implements Handler { protected Http11AprProtocol proto; - protected static int count = 0; + protected AtomicInteger registerCount = new AtomicInteger(0); protected RequestGroupInfo global = new RequestGroupInfo(); - protected ThreadLocal<Http11AprProcessor> localProcessor = - new ThreadLocal<Http11AprProcessor>(); protected ConcurrentHashMap<Long, Http11AprProcessor> connections = new ConcurrentHashMap<Long, Http11AprProcessor>(); - protected java.util.Stack<Http11AprProcessor> recycledProcessors = - new java.util.Stack<Http11AprProcessor>(); + protected ConcurrentLinkedQueue<Http11AprProcessor> recycledProcessors = + new ConcurrentLinkedQueue<Http11AprProcessor>() { + protected AtomicInteger size = new AtomicInteger(0); + public boolean offer(Http11AprProcessor 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 Http11AprProcessor poll() { + Http11AprProcessor result = super.poll(); + if ( result != null ) { + size.decrementAndGet(); + } + return result; + } + + public void clear() { + Http11AprProcessor next = poll(); + while ( next != null ) { + unregister(next); + next = poll(); + } + super.clear(); + size.set(0); + } + }; + Http11ConnectionHandler(Http11AprProtocol proto) { this.proto = proto; @@ -649,7 +647,7 @@ } finally { if (state != SocketState.LONG) { connections.remove(socket); - recycledProcessors.push(result); + recycledProcessors.offer(result); } } } @@ -657,47 +655,10 @@ } public SocketState process(long socket) { - Http11AprProcessor processor = null; + Http11AprProcessor processor = recycledProcessors.poll(); try { - processor = (Http11AprProcessor) localProcessor.get(); - if (processor == null) { - synchronized (recycledProcessors) { - if (!recycledProcessors.isEmpty()) { - processor = recycledProcessors.pop(); - localProcessor.set(processor); - } - } - } if (processor == null) { - processor = - new Http11AprProcessor(proto.maxHttpHeaderSize, proto.ep); - processor.setAdapter(proto.adapter); - processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests); - 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.setSocketBuffer(proto.socketBuffer); - processor.setMaxSavePostSize(proto.maxSavePostSize); - processor.setServer(proto.server); - 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=HttpRequest" + count++); - Registry.getRegistry(null, null).registerComponent(rp, rpName, null); - } catch (Exception e) { - log.warn("Error registering request"); - } - } - } + processor = createProcessor(); } if (processor instanceof ActionHook) { @@ -710,8 +671,9 @@ // processed by this thread will use either a new or a recycled // processor. connections.put(socket, processor); - localProcessor.set(null); - proto.ep.getCometPoller().add(socket); + proto.endpoint.getCometPoller().add(socket); + } else { + recycledProcessors.offer(processor); } return state; @@ -736,12 +698,72 @@ Http11AprProtocol.log.error (sm.getString("http11protocol.proto.error"), e); } + recycledProcessors.offer(processor); return SocketState.CLOSED; } - } - protected static org.apache.juli.logging.Log log - = org.apache.juli.logging.LogFactory.getLog(Http11AprProtocol.class); + protected Http11AprProcessor createProcessor() { + Http11AprProcessor processor = + new Http11AprProcessor(proto.maxHttpHeaderSize, proto.endpoint); + processor.setAdapter(proto.adapter); + processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests); + 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.setSocketBuffer(proto.socketBuffer); + processor.setMaxSavePostSize(proto.maxSavePostSize); + processor.setServer(proto.server); + register(processor); + return processor; + } + + protected void register(Http11AprProcessor 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(Http11AprProcessor 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); + } + } + } + } + + } // -------------------- Various implementation classes -------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]