Hi, 

attached you'll find a patch that changes the coyote multithreading
model to a "hybrid" threading model (NIO+Mulithread). It's fully
compatible with the existing Catalina code and is SSL enabled.

The Hybrid model breaks the limitation of one thread per connection,
thus you can have a higher number of concurrent users with a lower
number of threads.
NIO selectors are utilized to detect when a user connection becomes
active ( i.e. there is a user http request available to be read), and
then, one thread processes the connection as usual, but without blocking
on the read() operation because we know that there is one available
request.


The Hybrid model eliminates the need to close inactive connections
(especially important under high load or SSL load) and reduces the
number of necessary threads.


The patch will be also downloadable  in short from
http://www.bsc.es/edragon/.  Next week I will make available a
performance comparison between Tomcat 5.5.9 and the modified Tomcat
(Static content, Dynamic content, Secure Dynamic Content and scalability
on SMP machines). I'm testing it with RUBiS, Surge and httperf.


Now, I am working on the admission control mechanism because it should
be improved. (The number of threads doesn't limit the number of
concurrent connections so we need to limit it in some way).



Best Regards, 

Vicenç Beltran 

eDragon Research Group
Barcelona Supercomputing Center (BSC)
http://www.bsc.es/edragon



===================================================================
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/conf/server.xml 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/catalina/src/conf/server.xml
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/conf/server.xml   
Sat Mar 26 20:23:58 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/catalina/src/conf/server.xml
      Thu May 19 18:58:52 2005
@@ -73,10 +73,10 @@
     -->
 
     <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
-    <Connector port="8080" maxHttpHeaderSize="8192"
-               maxThreads="150" minSpareThreads="25"
maxSpareThreads="75"
+    <Connector port="8080" maxHttpHeaderSize="8192"
maxActiveRequest="100"
+               maxThreads="40" minSpareThreads="10"
maxSpareThreads="10"
                enableLookups="false" redirectPort="8443"
acceptCount="100"
-               connectionTimeout="20000" disableUploadTimeout="true" />
+               connectionTimeout="0" disableUploadTimeout="true" />
     <!-- Note : To disable connection timeouts, set connectionTimeout
value
      to 0 -->
        
@@ -90,11 +90,11 @@
 
     <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
     <!--
-    <Connector port="8443" maxHttpHeaderSize="8192"
-               maxThreads="150" minSpareThreads="25"
maxSpareThreads="75"
+    <Connector port="8443" maxHttpHeaderSize="8192"
maxActiveRequest="100"
+               maxThreads="40" minSpareThreads="10"
maxSpareThreads="10"
                enableLookups="false" disableUploadTimeout="true"
                acceptCount="100" scheme="https" secure="true"
-               clientAuth="false" sslProtocol="TLS" />
+               connectionTimeout="0" clientAuth="false"
sslProtocol="TLS" />
     -->
 
     <!-- Define an AJP 1.3 Connector on port 8009 -->
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/mbeans-descriptors.xml
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/mbeans-descriptors.xml
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/mbeans-descriptors.xml
        Sat Mar 26 20:23:59 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/mbeans-descriptors.xml
   Thu May 19 12:29:07 2005
@@ -8,6 +8,12 @@
                 group="Connector"
                  type="org.apache.catalina.connector.Connector">
 
+    <attribute   name="maxActiveRequests"
+          description="Maximum number of active requests"
+                 type="int"
+            readable="true"
+           writeable="true"/>
+
     <attribute   name="acceptCount"
           description="The accept count for this Connector"
                  type="int"/>
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/webapps/docs/config/http.xml 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/webapps/docs/config/http.xml
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/webapps/docs/config/http.xml   
Sat Mar 26 20:24:09 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-catalina/webapps/docs/config/http.xml
      Thu May 19 12:28:17 2005
@@ -57,6 +57,11 @@
 
   <attributes>
 
+    <attribute name="maxActiveRequests" required="false">
+      <p>A integer value which can be used to adjust Tomcat response
time
+        under high load.</p>
+    </attribute>
+
     <attribute name="allowTrace" required="false">
       <p>A boolean value which can be used to enable or disable the
TRACE
       HTTP method. If not specified, this attribute is set to
false.</p>
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java
        Sat Mar 26 20:24:10 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java
   Thu May 19 19:03:10 2005
@@ -17,6 +17,7 @@
 package org.apache.coyote.http11;
 
 import java.io.IOException;
+import java.net.SocketTimeoutException;
 import java.io.InputStream;
 import java.io.InterruptedIOException;
 import java.io.OutputStream;
@@ -774,7 +775,7 @@ public class Http11Processor implements 
         // Error flag
         error = false;
         keepAlive = true;
-
+/*
         int keepAliveLeft = maxKeepAliveRequests;
         int soTimeout = socket.getSoTimeout();
         int oldSoTimeout = soTimeout;
@@ -805,25 +806,33 @@ public class Http11Processor implements 
                 error = true;
             }
         }
+*/
 
         boolean keptAlive = false;
 
-        while (started && !error && keepAlive) {
+       boolean available = true;
+
+        while (started && available && !error && keepAlive) {
 
-            // Parsing the request header
+           // Parsing the request header
             try {
-                if( !disableUploadTimeout && keptAlive && soTimeout > 0
) {
+/*                if( !disableUploadTimeout && keptAlive && soTimeout >
0 ) {
                     socket.setSoTimeout(soTimeout);
                 }
+*/             socket.setSoTimeout(10);
                 inputBuffer.parseRequestLine();
+
                 request.setStartTime(System.currentTimeMillis());
                 thrA.setParam( threadPool, request.requestURI() );
                 keptAlive = true;
                 if (!disableUploadTimeout) {
                     socket.setSoTimeout(timeout);
-                }
+                } else socket.setSoTimeout(0);
+
                 inputBuffer.parseHeaders();
-            } catch (IOException e) {
+           } catch(SocketTimeoutException ste){
+                break;
+           } catch (IOException e) {
                 error = true;
                 break;
             } catch (Throwable t) {
@@ -845,8 +854,8 @@ public class Http11Processor implements 
                 error = true;
             }
 
-            if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
-                keepAlive = false;
+//            if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
+//                keepAlive = false;
 
             // Process the request in the adapter
             if (!error) {
@@ -914,9 +923,22 @@ public class Http11Processor implements 
             // Next request
             inputBuffer.nextRequest();
             outputBuffer.nextRequest();
-
+               
+           available = inputBuffer.available();
         }
 
+// eDragon
+
+
+       if(error || !keepAlive){
+               try{
+                       socket.close();
+               } catch (Exception e) { 
+                       e.printStackTrace(); 
+               }
+       } 
+
+
         rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
 
         // Recycle
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Protocol.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Protocol.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Protocol.java
 Sat Mar 26 20:24:10 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11Protocol.java
    Thu May 19 12:23:03 2005
@@ -239,7 +239,7 @@ public class Http11Protocol implements P
     private String reportedname;
     private int socketCloseDelay=-1;
     private boolean disableUploadTimeout = true;
-    private int socketBuffer = 9000;
+    private int socketBuffer = 8192; //  El famos bug:  
NIO+SSL+(buff>8192)  => BUG!!!
     private Adapter adapter;
     private Http11ConnectionHandler cHandler;
 
@@ -283,6 +283,15 @@ public class Http11Protocol implements P
         setAttribute("minSpareThreads", "" + minSpareThreads);
     }
 
+/* JMX */
+    public void setMaxActiveRequests(int MaxActiveRequests) {
+       ep.setMaxActiveRequests(MaxActiveRequests);
+    }
+
+    public int getMaxActiveRequests(){ 
+       return ep.getMaxActiveRequests();
+    }
+
     public void setThreadPriority(int threadPriority) {
       ep.setThreadPriority(threadPriority);
       setAttribute("threadPriority", "" + threadPriority);
@@ -749,13 +758,15 @@ public class Http11Protocol implements P
                 // type of error, provide a configurable delay to give
the
                 // unread input time to arrive so it can be
successfully read
                 // and discarded by shutdownInput().
+/* eDragon
                 if( proto.socketCloseDelay >= 0 ) {
                     try {
                         Thread.sleep(proto.socketCloseDelay);
-                    } catch (InterruptedException ie) { /* ignore */ }
+                    } catch (InterruptedException ie) {  }
                 }
 
                 TcpConnection.shutdownInput( socket );
+*/
             } catch(java.net.SocketException e) {
                 // SocketExceptions are normal
                 Http11Protocol.log.debug
@@ -783,9 +794,11 @@ public class Http11Protocol implements P
                 if (processor instanceof ActionHook) {
                     ((ActionHook)
processor).action(ActionCode.ACTION_STOP, null);
                 }
+/* eDragon
                 // recycle kernel sockets ASAP
                 try { if (socket != null) socket.close (); }
-                catch (IOException e) { /* ignore */ }
+                catch (IOException e) {  }
+*/
             }
         }
     }
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java
    Sat Mar 26 20:24:10 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalInputBuffer.java
       Wed May 18 10:47:47 2005
@@ -371,6 +371,9 @@ public class InternalInputBuffer impleme
 
     }
 
+    public boolean available(){
+       return pos < lastValid;
+    }
 
     /**
      * Read the request line. This function is meant to be used during
the 
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
 Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
    Thu May 19 12:37:29 2005
@@ -18,6 +18,9 @@ package org.apache.tomcat.util.net;
 
 import java.io.*;
 import java.net.*;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.net.InetSocketAddress;
 
 /**
  * Default server socket factory. Doesn't do much except give us
@@ -25,8 +28,10 @@ import java.net.*;
  *
  * @author [EMAIL PROTECTED]
  * @author Harish Prabandham
+ * @author Vicenç Beltran
  */
 
+
 // Default implementation of server sockets.
 
 //
@@ -41,23 +46,33 @@ class DefaultServerSocketFactory extends
 
     public ServerSocket createSocket (int port)
     throws IOException {
-        return  new ServerSocket (port);
+       ServerSocketChannel ssc = ServerSocketChannel.open();
+        return ssc.socket();
     }
 
     public ServerSocket createSocket (int port, int backlog)
     throws IOException {
-        return new ServerSocket (port, backlog);
+
+       InetSocketAddress isa = new InetSocketAddress(port);
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(isa, backlog);
+        return ssc.socket();
     }
 
     public ServerSocket createSocket (int port, int backlog,
         InetAddress ifAddress)
     throws IOException {
-        return new ServerSocket (port, backlog, ifAddress);
+       InetSocketAddress isa = new InetSocketAddress(ifAddress, port);
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(isa, backlog);
+        return ssc.socket();
     }
  
     public Socket acceptSocket(ServerSocket socket)
        throws IOException {
-       return socket.accept();
+       SocketChannel channel = socket.getChannel().accept();
+       if (channel != null) return channel.socket();
+       else return null;
     }
  
     public void handshake(Socket sock)
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/LeaderFollowerWorkerThread.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/LeaderFollowerWorkerThread.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/LeaderFollowerWorkerThread.java
 Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/LeaderFollowerWorkerThread.java
    Thu May 19 19:06:29 2005
@@ -16,71 +16,182 @@
 
 package org.apache.tomcat.util.net;
 
-import java.net.Socket;
 import org.apache.tomcat.util.threads.ThreadPoolRunnable;
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.util.Set;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.io.IOException;
+import java.net.Socket;
 
-/*
- * I switched the threading model here.
- *
- * We used to have a "listener" thread and a "connection"
- * thread, this results in code simplicity but also a needless
- * thread switch.
- *
- * Instead I am now using a pool of threads, all the threads are
- * simmetric in their execution and no thread switch is needed.
+/**
+ * @author Vicenç Beltran
  */
+
 class LeaderFollowerWorkerThread implements ThreadPoolRunnable {
-    /* This is not a normal Runnable - it gets attached to an existing
-       thread, runs and when run() ends - the thread keeps running.
 
-       It's better to keep the name ThreadPoolRunnable - avoid
confusion.
-       We also want to use per/thread data and avoid sync wherever
possible.
-    */
-    PoolTcpEndpoint endpoint;
+/* JMX */      
+    private static int maxActiveRequests=100;
+
+    static public void setMaxActiveRequests(int  MaxActiveRequests){
+       maxActiveRequests = MaxActiveRequests;
+       System.out.println("MaxActiveRequests:  "+maxActiveRequests);
+    }
+
+    static public int getMaxActiveRequests(){
+        return maxActiveRequests;
+    }
+/* JMX */      
+
+    private PoolTcpEndpoint endpoint;
+
+    private LinkedList<Socket> registeredSocketList;
+    private LinkedList<Socket> preAcceptedSockets;
+
+    private Iterator<SelectionKey> iterator;
+    private SelectionKey slkAccept;
+    private Selector selector;
+
+    private int filteredActiveRequests;
+    private int numSelectedKeys; 
+    private int count;
     
-    public LeaderFollowerWorkerThread(PoolTcpEndpoint endpoint) {
-        this.endpoint = endpoint;
+    public LeaderFollowerWorkerThread (PoolTcpEndpoint Endpoint) {
+
+        endpoint = Endpoint;
+       preAcceptedSockets = new LinkedList<Socket>();
+       registeredSocketList = new LinkedList<Socket>();
+
+        try{
+                selector = Selector.open();
+        } catch(IOException e) { e.printStackTrace(); }
+
+       iterator = selector.selectedKeys().iterator();
+
+       ServerSocketChannel ssc = endpoint.getServerSocket().getChannel();
+        slkAccept = null;
+        try{
+                ssc.configureBlocking(false);
+                slkAccept = ssc.register(selector,
SelectionKey.OP_ACCEPT);
+        }catch (Exception e) { e.printStackTrace(); }
+
+       filteredActiveRequests = 0;
+       numSelectedKeys = 0;
+       count = 0;
     }
 
     public Object[] getInitData() {
-        // no synchronization overhead, but 2 array access 
         Object obj[]=new Object[2];
         obj[1]= endpoint.getConnectionHandler().init();
         obj[0]=new TcpConnection();
         return obj;
     }
-    
+ 
     public void runIt(Object perThrData[]) {
 
-        // Create per-thread cache
-        if (endpoint.isRunning()) {
-
-            // Loop if endpoint is paused
-            while (endpoint.isPaused()) {
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-
-            // Accept a new connection
-            Socket s = null;
+       // Loop if endpoint is paused
+        while (endpoint.isPaused()) {
             try {
-                s = endpoint.acceptSocket();
-            } finally {
-                // Continue accepting on another thread...
-                if (endpoint.isRunning()) {
-                    endpoint.tp.runIt(this);
-                }
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // Ignore
             }
+        }
 
-            // Process the connection
-            if (null != s) {
-                endpoint.processSocket(s, (TcpConnection)
perThrData[0], (Object[]) perThrData[1]);
-            }
+       Socket socket = null;
+       long localTime = System.nanoTime();
 
+       try{
+           while(!iterator.hasNext() && preAcceptedSockets.isEmpty()) {
+               
+               if(registeredSocketList.isEmpty()) doSelect();
+               else doSelectNow();
+
+               filteredActiveRequests = 
(filteredActiveRequests+numSelectedKeys)/2;
+               doAcceptNow(maxActiveRequests-filteredActiveRequests);
+           }
+
+
+           if(preAcceptedSockets.size()*count >= numSelectedKeys){
+               count = 0;
+               socket = preAcceptedSockets.poll();
+           } else {
+               count++;
+               SelectionKey key = iterator.next(); 
+               socket = (Socket)key.attachment();
+               key.cancel();
+               socket.getChannel().configureBlocking(true);
+               numSelectedKeys--;
+           } 
+        } catch (IOException e){  
+           e.printStackTrace(); 
+        } finally {
+           endpoint.tp.runIt(this);
         }
+       
+       try{
+               endpoint.processSocket(socket, (TcpConnection) perThrData[0],
(Object[]) perThrData[1]);
+
+               synchronized(registeredSocketList){
+                       registeredSocketList.add(socket);
+               }
+               selector.wakeup();
+
+       } catch(Exception e) { 
+               e.printStackTrace();
+       }
     }
-    
+
+
+
+    private void doAcceptNow(int max) {
+
+       Socket s;
+        for(int i=0; i<max; i++){
+            if((s = endpoint.acceptSocket()) == null) return;
+            preAcceptedSockets.add(s);
+        }
+    }
+
+
+    private void doSelect() throws IOException {
+
+        selector.select();
+
+       registerSockets();              
+       selector.selectedKeys().remove(slkAccept);
+       numSelectedKeys = selector.selectedKeys().size();
+        iterator = selector.selectedKeys().iterator();
+    }
+
+
+    private void doSelectNow() throws IOException{
+       
+       selector.selectNow();
+       registerSockets();              
+       selector.selectNow();
+       selector.selectedKeys().remove(slkAccept);
+       numSelectedKeys = selector.selectedKeys().size();
+       iterator = selector.selectedKeys().iterator();
+    }
+
+
+    private void registerSockets(){
+        Socket socket;
+        synchronized(registeredSocketList){
+            while((socket = registeredSocketList.poll()) !=null){
+                try{
+                        if(!socket.isClosed()){
+                               
socket.getChannel().configureBlocking(false);
+                                socket.getChannel().register(selector,
SelectionKey.OP_READ, socket);
+                        }
+                } catch (Exception e) {
+                        e.printStackTrace();
+                }
+            }
+        }
+    }
+
 }
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
    Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
       Thu May 19 12:20:53 2005
@@ -88,7 +88,7 @@ public class PoolTcpEndpoint implements 
     protected int socketTimeout=-1;
     private boolean lf = true;
 
-    
+
     // ------ Leader follower fields
 
     
@@ -96,7 +96,7 @@ public class PoolTcpEndpoint implements 
     ThreadPoolRunnable listener;
     ThreadPool tp;
 
-    
+
     // ------ Master slave fields
 
     /* The background thread. */
@@ -119,6 +119,15 @@ public class PoolTcpEndpoint implements 
 
     // -------------------- Configuration --------------------
 
+    public void setMaxActiveRequests(int  MaxActiveRequests){
+       LeaderFollowerWorkerThread.setMaxActiveRequests(MaxActiveRequests);
+    }
+
+    public int getMaxActiveRequests(){
+       return LeaderFollowerWorkerThread.getMaxActiveRequests();
+    }
+
+
     public void setMaxThreads(int maxThreads) {
        if( maxThreads > 0)
            tp.setMaxThreads(maxThreads);
@@ -174,6 +183,10 @@ public class PoolTcpEndpoint implements 
            serverSocket = ss;
     }
 
+    public ServerSocket getServerSocket(){
+       return serverSocket;
+    }
+
     public void setServerSocketFactory(  ServerSocketFactory factory )
{
            this.factory=factory;
     }
@@ -275,11 +288,11 @@ public class PoolTcpEndpoint implements 
     public int getCurrentThreadCount() {
         return curThreads;
     }
-    
-    public int getCurrentThreadsBusy() {
-        return curThreads - workerThreads.size();
+
+    public int getCurrentThreadsBusy(){
+       return tp.getCurrentThreadsBusy();
     }
-    
+
     // -------------------- Public methods --------------------
 
     public void initEndpoint() throws IOException,
InstantiationException {
@@ -304,25 +317,31 @@ public class PoolTcpEndpoint implements 
         } catch( InstantiationException ex1 ) {
             throw ex1;
         }
+
+
         initialized = true;
     }
     
     public void startEndpoint() throws IOException,
InstantiationException {
-        if (!initialized) {
+     if (!initialized) {
             initEndpoint();
         }
         if (lf) {
             tp.start();
-        }
+        } 
         running = true;
         paused = false;
         if (lf) {
-            listener = new LeaderFollowerWorkerThread(this);
-            tp.runIt(listener);
+           for(int i=0; i<4; i++){
+           LeaderFollowerWorkerThread  listener = new
LeaderFollowerWorkerThread(this);
+               tp.runIt(listener);
+           }
         } else {
             maxThreads = getMaxThreads();
             threadStart();
-        }
+        } 
+
+
     }
 
     public void pauseEndpoint() {
@@ -407,7 +426,7 @@ public class PoolTcpEndpoint implements 
                 accepted = factory.acceptSocket(serverSocket);
             }
             if (null == accepted) {
-                log.warn(sm.getString("endpoint.warn.nullSocket"));
+               // log.warn(sm.getString("endpoint.warn.nullSocket"));
             } else {
                 if (!running) {
                     accepted.close();  // rude, but unlikely!
@@ -513,13 +532,13 @@ public class PoolTcpEndpoint implements 
             
             // 1: Set socket options: timeout, linger, etc
             setSocketOptions(s);
-            
+
             // 2: SSL handshake
             step = 2;
             if (getServerSocketFactory() != null) {
                 getServerSocketFactory().handshake(s);
             }
-            
+ 
             // 3: Process the connection
             step = 3;
             con.setEndpoint(this);
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java
   Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java
      Wed May 18 10:47:47 2005
@@ -146,6 +146,14 @@ public class JSSE13SocketFactory extends
         socket.setNeedClientAuth(clientAuth);
     }
 
+    protected String[] getEnabledProtocols(SSLSocket socket,
+                                           String requestedProtocols){
+        return null;
+    }
+    protected void setEnabledProtocols(SSLSocket socket,
+                                             String [] protocols){
+    }
+    
     protected void configureClientAuth(SSLSocket socket){
         // In JSSE 1.0.2 docs it does not explicitly
         // state whether SSLSockets returned from 
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java
   Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java
      Wed May 18 10:47:47 2005
@@ -114,6 +114,8 @@ public class JSSE14SocketFactory  extend
             // create proxy
             sslProxy = context.getServerSocketFactory();
 
+           sslProxy2 = context.getSocketFactory();
+
             // Determine which cipher suites to enable
             String requestedCiphers =
(String)attributes.get("ciphers");
             enabledCiphers = getEnabledCiphers(requestedCiphers,
@@ -180,12 +182,20 @@ public class JSSE14SocketFactory  extend
 
         return tms;
     }
+
+
     protected void setEnabledProtocols(SSLServerSocket socket, String
[]protocols){
         if (protocols != null) {
             socket.setEnabledProtocols(protocols);
         }
     }
 
+     protected void setEnabledProtocols(SSLSocket socket, String
[]protocols){
+        if (protocols != null) {
+            socket.setEnabledProtocols(protocols);
+        }
+    }  
+
     protected String[] getEnabledProtocols(SSLServerSocket socket,
                                            String requestedProtocols){
         String[] supportedProtocols = socket.getSupportedProtocols();
@@ -251,6 +261,74 @@ public class JSSE14SocketFactory  extend
         return enabledProtocols;
     }
 
+
+    protected String[] getEnabledProtocols(SSLSocket socket,
+                                           String requestedProtocols){
+        String[] supportedProtocols = socket.getSupportedProtocols();
+
+        String[] enabledProtocols = null;
+
+        if (requestedProtocols != null) {
+            Vector vec = null;
+            String protocol = requestedProtocols;
+            int index = requestedProtocols.indexOf(',');
+            if (index != -1) {
+                int fromIndex = 0;
+                while (index != -1) {
+                    protocol = requestedProtocols.substring(fromIndex,
index).trim();
+                    if (protocol.length() > 0) {
+                        /*
+                         * Check to see if the requested protocol is
among the
+                         * supported protocols, i.e., may be enabled
+                         */
+                        for (int i=0; supportedProtocols != null
+                                     && i<supportedProtocols.length;
i++) {
+                            if (supportedProtocols[i].equals(protocol))
{
+                                if (vec == null) {
+                                    vec = new Vector();
+                                }
+                                vec.addElement(protocol);
+                                break;
+                            }
+                        }
+                    }
+                    fromIndex = index+1;
+                    index = requestedProtocols.indexOf(',', fromIndex);
+                } // while
+                protocol = requestedProtocols.substring(fromIndex);
+            }
+
+            if (protocol != null) {
+                protocol = protocol.trim();
+                if (protocol.length() > 0) {
+                    /*
+                     * Check to see if the requested protocol is among
the
+                     * supported protocols, i.e., may be enabled
+                     */
+                    for (int i=0; supportedProtocols != null
+                                 && i<supportedProtocols.length; i++) {
+                        if (supportedProtocols[i].equals(protocol)) {
+                            if (vec == null) {
+                                vec = new Vector();
+                            }
+                            vec.addElement(protocol);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (vec != null) {
+                enabledProtocols = new String[vec.size()];
+                vec.copyInto(enabledProtocols);
+            }
+        }
+
+        return enabledProtocols;
+    }
+
+
+
     protected void configureClientAuth(SSLServerSocket socket){
         if (wantClientAuth){
             socket.setWantClientAuth(wantClientAuth);
@@ -263,5 +341,4 @@ public class JSSE14SocketFactory  extend
         // Per JavaDocs: SSLSockets returned from 
         // SSLServerSocket.accept() inherit this setting.
     }
-    
 }
diff -uprN
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
 
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
---
jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
     Sat Mar 26 20:24:17 2005
+++
jakarta-tomcat-5.5.9-src+STWS/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
        Wed May 18 10:47:47 2005
@@ -32,6 +32,10 @@ import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.net.InetSocketAddress;
 
 /*
   1. Make the JSSE's jars available, either as an installed
@@ -49,6 +53,7 @@ import javax.net.ssl.SSLSocket;
  * @author Costin Manolache
  * @author Stefan Freyr Stefansson
  * @author EKR -- renamed to JSSESocketFactory
+ * @author Vicenç Beltran
  */
 public abstract class JSSESocketFactory
     extends org.apache.tomcat.util.net.ServerSocketFactory
@@ -68,7 +73,8 @@ public abstract class JSSESocketFactory
     protected String clientAuth = "false";
     protected SSLServerSocketFactory sslProxy = null;
     protected String[] enabledCiphers;
-   
+
+    protected SSLSocketFactory sslProxy2 = null;
 
     public JSSESocketFactory () {
     }
@@ -77,18 +83,20 @@ public abstract class JSSESocketFactory
         throws IOException
     {
         if (!initialized) init();
-        ServerSocket socket = sslProxy.createServerSocket(port);
-        initServerSocket(socket);
-        return socket;
+
+        ServerSocketChannel ssc =  ServerSocketChannel.open();
+        return ssc.socket();
     }
     
     public ServerSocket createSocket (int port, int backlog)
         throws IOException
     {
         if (!initialized) init();
-        ServerSocket socket = sslProxy.createServerSocket(port,
backlog);
-        initServerSocket(socket);
-        return socket;
+
+       InetSocketAddress isa = new InetSocketAddress(port);
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(isa, backlog);
+       return ssc.socket();
     }
     
     public ServerSocket createSocket (int port, int backlog,
@@ -96,19 +104,24 @@ public abstract class JSSESocketFactory
         throws IOException
     {   
         if (!initialized) init();
-        ServerSocket socket = sslProxy.createServerSocket(port,
backlog,
-                                                          ifAddress);
-        initServerSocket(socket);
-        return socket;
+       InetSocketAddress isa = new InetSocketAddress(ifAddress, port);
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(isa, backlog);
+       return ssc.socket();
     }
-    
+
     public Socket acceptSocket(ServerSocket socket)
         throws IOException
     {
         SSLSocket asock = null;
         try {
-             asock = (SSLSocket)socket.accept();
-             configureClientAuth(asock);
+
+            SocketChannel channel = socket.getChannel().accept();
+            if(channel == null) return null;   
+            Socket sk = channel.socket();
+            asock = (SSLSocket) sslProxy2.createSocket(sk,
sk.getInetAddress().getHostName(), sk.getPort(), true); 
+            initSocket(asock);
+            asock.setUseClientMode(false);
         } catch (SSLException e){
           throw new SocketException("SSL handshake error" +
e.toString());
         }
@@ -116,7 +129,7 @@ public abstract class JSSESocketFactory
     }
 
     public void handshake(Socket sock) throws IOException {
-        ((SSLSocket)sock).startHandshake();
+       ((SSLSocket)sock).getSession();
     }
 
     /*
@@ -321,6 +334,10 @@ public abstract class JSSESocketFactory
     abstract protected String[] getEnabledProtocols(SSLServerSocket
socket,
                                                     String
requestedProtocols);
 
+  
+    abstract protected String[] getEnabledProtocols(SSLSocket socket,
+                                                    String
requestedProtocols);
+
     /**
      * Set the SSL protocol variants to be enabled.
      * @param socket the SSLServerSocket.
@@ -329,6 +346,9 @@ public abstract class JSSESocketFactory
     abstract protected void setEnabledProtocols(SSLServerSocket socket,
                                             String [] protocols);
 
+
+    abstract protected void setEnabledProtocols(SSLSocket socket,
+                                            String [] protocols);
     /**
      * Configure Client authentication for this version of JSSE.  The
      * JSSE included in Java 1.4 supports the 'want' value.  Prior
@@ -366,4 +386,21 @@ public abstract class JSSESocketFactory
         configureClientAuth(socket);
     }
 
+    private void initSocket(SSLSocket socket) {
+
+
+        if (enabledCiphers != null) {
+            socket.setEnabledCipherSuites(enabledCiphers);
+        }
+
+        String requestedProtocols = (String)
attributes.get("protocols");
+        setEnabledProtocols(socket, getEnabledProtocols(socket,
+                                                        
requestedProtocols));
+
+        // we don't know if client auth is needed -
+        // after parsing the request we may re-handshake
+        configureClientAuth(socket);
+    }
+
+
 }
===================================================================



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to