tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jfcl...@apache.org
Subject svn commit: r948795 - in /tomcat/trunk/java/org/apache/coyote/ajp: AjpAprProcessor.java AjpAprProtocol.java
Date Thu, 27 May 2010 12:05:51 GMT
Author: jfclere
Date: Thu May 27 12:05:50 2010
New Revision: 948795

URL: http://svn.apache.org/viewvc?rev=948795&view=rev
Log:
Fix APR AJP logic.

Modified:
    tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
    tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=948795&r1=948794&r2=948795&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java Thu May 27 12:05:50 2010
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 
@@ -44,6 +45,8 @@ import org.apache.tomcat.util.http.HttpM
 import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.AprEndpoint;
+import org.apache.tomcat.util.net.SocketStatus;
+import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
 import org.apache.tomcat.util.res.StringManager;
 
 
@@ -183,6 +186,10 @@ public class AjpAprProcessor implements 
      */
     protected boolean error = false;
 
+    /**
+      * Async used
+      */
+    protected boolean async = false;
 
     /**
      * Socket associated with the current connection.
@@ -366,6 +373,7 @@ public class AjpAprProcessor implements 
 
         // Error flag
         error = false;
+        async = false;
 
         boolean openSocket = true;
         boolean keptAlive = false;
@@ -437,6 +445,10 @@ public class AjpAprProcessor implements 
                 }
             }
 
+            if (async && !error) {
+                break;
+            }
+
             // Finish the response if not done yet
             if (!finished) {
                 try {
@@ -466,12 +478,53 @@ public class AjpAprProcessor implements 
         }
 
         rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-        recycle();
+        if (!async || error)
+             recycle();
 
         return openSocket;
 
     }
 
+    /* Copied from the AjpProcessor.java */
+    public SocketState asyncDispatch(long socket, SocketStatus status) throws IOException
{
+
+        // Setting up the socket
+        this.socket = socket;
+
+        RequestInfo rp = request.getRequestProcessor();
+        try {
+            rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
+            error = !adapter.asyncDispatch(request, response, status);
+        } catch (InterruptedIOException e) {
+            error = true;
+        } catch (Throwable t) {
+            log.error(sm.getString("http11processor.request.process"), t);
+            // 500 - Internal Server Error
+            response.setStatus(500);
+            error = true;
+        }
+
+        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
+
+        if (async) {
+            if (error) {
+                response.setStatus(500);
+                request.updateCounters();
+                recycle();
+                return SocketState.CLOSED;
+            } else {
+                return SocketState.LONG;
+            }
+        } else {
+            if (error) {
+                response.setStatus(500);
+            }
+            request.updateCounters();
+            recycle();
+            return SocketState.CLOSED;
+        }
+        
+    }
 
     // ----------------------------------------------------- ActionHook Methods
 
@@ -524,6 +577,7 @@ public class AjpAprProcessor implements 
 
         } else if (actionCode == ActionCode.ACTION_CLOSE) {
             // Close
+            async = false;
 
             // End the processing of the current request, and stop any further
             // transactions with the client
@@ -604,6 +658,31 @@ public class AjpAprProcessor implements 
             empty = false;
             replay = true;
 
+        } else if (actionCode == ActionCode.ACTION_ASYNC_START) {
+            async = true;
+        } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) {
+            AtomicBoolean dispatch = (AtomicBoolean)param;
+            RequestInfo rp = request.getRequestProcessor();
+            if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) { //async handling
+                dispatch.set(true);
+                endpoint.getHandler().asyncDispatch(this.socket, SocketStatus.STOP);
+            } else {
+                dispatch.set(false);
+            }        
+        } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) {
+            if (param==null) return;
+            if (socket==0) return;
+            long timeout = ((Long)param).longValue();
+            Socket.timeoutSet(socket, timeout * 1000); 
+        } else if (actionCode == ActionCode.ACTION_ASYNC_DISPATCH) {
+           RequestInfo rp = request.getRequestProcessor();
+            AtomicBoolean dispatch = (AtomicBoolean)param;
+            if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) {//async handling
+                endpoint.getPoller().add(this.socket);
+                dispatch.set(true);
+            } else {
+                dispatch.set(true);
+            }
         }
 
 

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java?rev=948795&r1=948794&r2=948795&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java Thu May 27 12:05:50 2010
@@ -21,6 +21,7 @@ import java.net.InetAddress;
 import java.net.URLEncoder;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -325,6 +326,9 @@ public class AjpAprProtocol 
         protected AtomicLong registerCount = new AtomicLong(0);
         protected RequestGroupInfo global = new RequestGroupInfo();
 
+        protected ConcurrentHashMap<Long, AjpAprProcessor> connections =
+            new ConcurrentHashMap<Long, AjpAprProcessor>();
+
         protected ConcurrentLinkedQueue<AjpAprProcessor> recycledProcessors = 
             new ConcurrentLinkedQueue<AjpAprProcessor>() {
             protected AtomicInteger size = new AtomicInteger(0);
@@ -384,8 +388,10 @@ public class AjpAprProtocol 
                 processor.action(ActionCode.ACTION_START, null);
 
                 if (processor.process(socket)) {
+                    connections.put(Long.valueOf(socket), processor);
                     return SocketState.OPEN;
                 } else {
+                    // recycledProcessors.offer(processor);
                     return SocketState.CLOSED;
                 }
 
@@ -418,7 +424,45 @@ public class AjpAprProtocol 
 
         // FIXME: Support for this could be added in AJP as well
         public SocketState asyncDispatch(long socket, SocketStatus status) {
-            return SocketState.CLOSED;
+
+            AjpAprProcessor result = connections.get(Long.valueOf(socket));
+            
+            SocketState state = SocketState.CLOSED; 
+            if (result != null) {
+                // Call the appropriate event
+                try {
+                    state = result.asyncDispatch(socket, status);
+                } catch (java.net.SocketException e) {
+                    // SocketExceptions are normal
+                    AjpAprProtocol.log.debug
+                        (sm.getString
+                            ("ajpprotocol.proto.socketexception.debug"), e);
+                } catch (java.io.IOException e) {
+                    // IOExceptions are normal
+                    AjpAprProtocol.log.debug
+                        (sm.getString
+                            ("ajpprotocol.proto.ioexception.debug"), e);
+                }
+                // Future developers: if you discover any other
+                // rare-but-nonfatal exceptions, catch them here, and log as
+                // above.
+                catch (Throwable e) {
+                    // any other exception or error is odd. Here we log it
+                    // with "ERROR" level, so it will show up even on
+                    // less-than-verbose logs.
+                    AjpAprProtocol.log.error
+                        (sm.getString("ajpprotocol.proto.error"), e);
+                } finally {
+                    if (state != SocketState.LONG) {
+                        connections.remove(Long.valueOf(socket));
+                        recycledProcessors.offer(result);
+                        if (state == SocketState.OPEN) {
+                            proto.endpoint.getPoller().add(socket);
+                        }
+                    }
+                }
+            }
+            return state;
         }
         
         protected AjpAprProcessor createProcessor() {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message