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]

Reply via email to