You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2007/04/17 03:50:36 UTC

svn commit: r529465 - in /tomcat/tc6.0.x/trunk/java/org/apache/coyote: ajp/AjpAprProtocol.java ajp/AjpProtocol.java http11/Http11AprProtocol.java http11/Http11Protocol.java

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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org