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 2006/09/13 02:55:16 UTC

svn commit: r442778 - in /tomcat/tc6.0.x/trunk/java/org/apache/catalina: ./ connector/ core/ servlets/ valves/

Author: remm
Date: Tue Sep 12 17:55:15 2006
New Revision: 442778

URL: http://svn.apache.org/viewvc?view=rev&rev=442778
Log:
- Redo Comet processing using events.
- Add Valve.event (most regular valves do not do anything, but standard valves need to call the next pipeline).
- Add a new Filter interface that filters can implement to intercept the events (I didn't test it yet).

Added:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java   (with props)
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java   (with props)
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java   (with props)
Removed:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java
Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java Tue Sep 12 17:55:15 2006
@@ -41,7 +41,8 @@
      *  it is possible to use the response object to write data on the open connection.
      *  Note that the response object and depedent OutputStream and Writer are still 
      *  not synchronized, so when they are accessed by multiple threads, 
-     *  synchronization is mandatory.
+     *  synchronization is mandatory. After processing the initial event, the request 
+     *  is considered to be committed.
      * READ - This indicates that input data is available, and that one read can be made
      *  without blocking. The available and ready methods of the InputStream or
      *  Reader may be used to determine if there is a risk of blocking: the servlet
@@ -61,7 +62,7 @@
      *  been processed, the request and response objects, as well as all their dependent
      *  objects will be recycled and used to process other requests.
      */
-    enum EventType {BEGIN, READ, END, ERROR}
+    public enum EventType {BEGIN, READ, END, ERROR}
     
     
     /**
@@ -73,7 +74,7 @@
      * SERVER_SHUTDOWN - the server is shutting down (sub type of END)
      * SESSION_END - the servlet ended the session (sub type of END)
      */
-    enum EventSubType { TIMEOUT, CLIENT_DISCONNECT, IOEXCEPTION, WEBAPP_RELOAD, SERVER_SHUTDOWN, SESSION_END }
+    public enum EventSubType { TIMEOUT, CLIENT_DISCONNECT, IOEXCEPTION, WEBAPP_RELOAD, SERVER_SHUTDOWN, SESSION_END }
     
     
     /**

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+
+/**
+ * The CometFilter interface.
+ * 
+ * @author Filip Hanik
+ */
+public interface CometFilter {
+
+    
+    public void doFilterEvent(CometEvent event, CometFilterChain chain) throws IOException, ServletException;
+    
+
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+/**
+ * The CometFilter interface.
+ * 
+ * @author Filip Hanik
+ */
+public interface CometFilterChain {
+
+    
+    public void doFilterEvent(CometEvent event) throws IOException, ServletException;
+    
+
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java Tue Sep 12 17:55:15 2006
@@ -20,8 +20,6 @@
 import java.io.IOException;
 
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 /**
  * This interface should be implemented by servlets which would like to handle
@@ -31,101 +29,13 @@
 public interface CometProcessor {
 
     /**
-     * Begin will be called by the main service method of the servlet at the beginning 
-     * of the processing of the connection. It can be used to initialize any relevant 
-     * fields using the request and response objects. Between the end of the execution 
-     * of this method, and the beginning of the execution of the end or error methods,
-     * it is possible to use the response object to write data on the open connection.
-     * Note that the response object and depedent OutputStream and Writer are still 
-     * not synchronized, so when they are accessed by multiple threads, 
-     * synchronization is mandatory.
+     * Process the given Comet event.
      * 
-     * @param request The HTTP servlet request instance, which can be accessed
-     *        asynchronously at any time until the end or error methods are called
-     * @param response The HTTP servlet response instance, which can be accessed
-     *        asynchronously at any time until the end or error methods are called
-     * @throws IOException An IOException may be thrown to indicate an IO error
-     * @throws ServletException An exception has occurred, as specified by the root
-     *         cause
+     * @param event The Comet event that will be processed
+     * @throws IOException
+     * @throws ServletException
      */
-    public void begin(HttpServletRequest request, HttpServletResponse response)
+    public void event(CometEvent event)
         throws IOException, ServletException;
-
-    /**
-     * End may be called to end the processing of the request. Fields that have
-     * been initialized in the begin method should be reset. After this method has
-     * been called, the request and response objects, as well as all their dependent
-     * objects will be recycled and used to process other requests.
-     * 
-     * @param request The HTTP servlet request instance
-     * @param response The HTTP servlet response instance
-     * @throws IOException An IOException may be thrown to indicate an IO error
-     * @throws ServletException An exception has occurred, as specified by the root
-     *         cause
-     */
-    public void end(HttpServletRequest request, HttpServletResponse response)
-        throws IOException, ServletException;
-
-    /**
-     * Error will be called by the container in the case where an IO exception
-     * or a similar unrecoverable error occurs on the connection. Fields that have
-     * been initialized in the begin method should be reset. After this method has
-     * been called, the request and response objects, as well as all their dependent
-     * objects will be recycled and used to process other requests.
-     * 
-     * @param request The HTTP servlet request instance
-     * @param response The HTTP servlet response instance
-     * @throws IOException An IOException may be thrown to indicate an IO error
-     * @throws ServletException An exception has occurred, as specified by the root
-     *         cause
-     */
-    public void error(HttpServletRequest request, HttpServletResponse response)
-        throws IOException, ServletException;
-    
-    /**
-     * This indicates that input data is available, and that one read can be made
-     * without blocking. The available and ready methods of the InputStream or
-     * Reader may be used to determine if there is a risk of blocking: the servlet
-     * should read while data is reported available, and can make one additional read
-     * without blocking. When encountering a read error or an EOF, the servlet MUST
-     * report it by either returning false or throwing an exception such as an 
-     * IOException. This will cause the error method to be invoked, and the connection
-     * will be closed. It is not allowed to attempt reading data from the request object
-     * outside of the execution of this method.
-     * 
-     * @param request The HTTP servlet request instance
-     * @param response The HTTP servlet response instance
-     * @throws IOException An IOException may be thrown to indicate an IO error, 
-     *         or that the EOF has been reached on the connection
-     * @throws ServletException An exception has occurred, as specified by the root
-     *         cause
-     * @return false if the read attempt returned an EOF; alternately, it is also
-     *         valid to throw an IOException
-     */
-    public boolean read(HttpServletRequest request, HttpServletResponse response)
-        throws IOException, ServletException;
-    
-    /**
-     * Sets the timeout for this Comet connection. Please NOTE, that the implementation 
-     * of a per connection timeout is OPTIONAL and MAY NOT be implemented.<br/>
-     * This method sets the timeout in milliseconds of idle time on the connection.
-     * The timeout is reset every time data is received from the connection or data is flushed
-     * using <code>response.flushBuffer()</code>. If a timeout occurs, the 
-     * <code>error(HttpServletRequest, HttpServletResponse)</code> method is invoked. The 
-     * web application SHOULD NOT attempt to reuse the request and response objects after a timeout
-     * as the <code>error(HttpServletRequest, HttpServletResponse)</code> method indicates.<br/>
-     * This method should not be called asynchronously, as that will have no effect.
-     * @param request The HTTP servlet request instance
-     * @param response The HTTP servlet response instance
-     * @param timeout The timeout in milliseconds for this connection, must be a positive value, larger than 0
-     * @throws IOException An IOException may be thrown to indicate an IO error, 
-     *         or that the EOF has been reached on the connection
-     * @throws ServletException An exception has occurred, as specified by the root
-     *         cause
-     * @throws UnsupportedOperationException if per connection timeout is not supported, either at all or at this phase
-     *         of the invocation.
-     */
-    public void setTimeout(HttpServletRequest request, HttpServletResponse response, int timeout)
-        throws IOException, ServletException, UnsupportedOperationException;
 
 }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java Tue Sep 12 17:55:15 2006
@@ -128,5 +128,20 @@
     public void invoke(Request request, Response response)
         throws IOException, ServletException;
 
+    
+    /**
+     * Process a Comet event.
+     *
+     * @param request The servlet request to be processed
+     * @param response The servlet response to be created
+     *
+     * @exception IOException if an input/output error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     * @exception ServletException if a servlet error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     */
+    public void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException;
+
 
 }

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina.connector;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.CometEvent;
+
+public class CometEventImpl implements CometEvent {
+
+
+    public CometEventImpl(Request request, Response response) {
+        this.request = request;
+        this.response = response;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+    
+    /**
+     * Associated request.
+     */
+    protected Request request = null;
+
+
+    /**
+     * Associated response.
+     */
+    protected Response response = null;
+
+    
+    /**
+     * Event type.
+     */
+    protected EventType eventType = EventType.BEGIN;
+    
+
+    /**
+     * Event sub type.
+     */
+    protected EventSubType eventSubType = null;
+    
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Clear the event.
+     */
+    public void clear() {
+        request = null;
+        response = null;
+    }
+
+    public void setEventType(EventType eventType) {
+        this.eventType = eventType;
+    }
+    
+    public void serEventSubType(EventSubType eventSubType) {
+        this.eventSubType = eventSubType;
+    }
+    
+    public void close() throws IOException {
+        request.setComet(false);
+        response.finishResponse();
+    }
+
+    public EventSubType getEventSubType() {
+        return eventSubType;
+    }
+
+    public EventType getEventType() {
+        return eventType;
+    }
+
+    public HttpServletRequest getHttpServletRequest() {
+        return request.getRequest();
+    }
+
+    public HttpServletResponse getHttpServletResponse() {
+        return response.getResponse();
+    }
+
+    public void setTimeout(int timeout) throws IOException, ServletException,
+            UnsupportedOperationException {
+        if (request.getAttribute("org.apache.tomcat.comet.timeout.support") == Boolean.TRUE) {
+            request.setAttribute("org.apache.tomcat.comet.timeout", new Integer(timeout));
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+}

Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Tue Sep 12 17:55:15 2006
@@ -21,6 +21,7 @@
 
 import javax.servlet.Servlet;
 
+import org.apache.catalina.CometEvent;
 import org.apache.catalina.CometProcessor;
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
@@ -119,29 +120,16 @@
 
         if (request.getWrapper() != null) {
             
-            CometProcessor servlet = null;
-
-            // Bind the context CL to the current thread
-            if (request.getContext().getLoader() != null ) {
-                Thread.currentThread().setContextClassLoader
-                        (request.getContext().getLoader().getClassLoader());
-            }
-            
             try {
-                servlet = (CometProcessor) request.getWrapper().allocate();
                 if (error) {
-                    servlet.error(request.getRequest(), response.getResponse());
+                    request.getEvent().setEventType(CometEvent.EventType.ERROR);
                 } else {
-                    if (!servlet.read(request.getRequest(), response.getResponse())) {
-                        error = true;
-                        try {
-                            servlet.error(request.getRequest(), response.getResponse());
-                        } catch (Throwable th) {
-                            log.error(sm.getString("coyoteAdapter.service"), th);
-                        }
-                    }
+                    request.getEvent().setEventType(CometEvent.EventType.READ);
                 }
-                if (response.isClosed()) {
+                // Calling the container
+                connector.getContainer().getPipeline().getFirst().event(request, response, request.getEvent());
+
+                if (response.isClosed() || !request.isComet()) {
                     res.action(ActionCode.ACTION_COMET_END, null);
                 }
                 return (!error);
@@ -150,24 +138,14 @@
                     log.error(sm.getString("coyoteAdapter.service"), t);
                 }
                 error = true;
-                try {
-                    servlet.error(request.getRequest(), response.getResponse());
-                } catch (Throwable th) {
-                    log.error(sm.getString("coyoteAdapter.service"), th);
-                }
+                // FIXME: Since there's likely some structures kept in the servlet or elsewhere,
+                // a cleanup event of some sort could be needed ?
                 return false;
             } finally {
-                // Restore the context classloader
-                Thread.currentThread().setContextClassLoader
-                    (CoyoteAdapter.class.getClassLoader());
-                try {
-                    request.getWrapper().deallocate((Servlet) servlet);
-                } catch (Exception e) {
-                    log.error(sm.getString("coyoteAdapter.service"), e);
-                }
                 // Recycle the wrapper request and response
-                if (error || response.isClosed()) {
+                if (error || response.isClosed() || !request.isComet()) {
                     request.recycle();
+                    request.setFilterChain(null);
                     response.recycle();
                 }
             }
@@ -223,11 +201,15 @@
                 // Calling the container
                 connector.getContainer().getPipeline().getFirst().invoke(request, response);
 
-                if (request.getWrapper().getServlet() instanceof CometProcessor 
-                        && !response.isClosed()
-                        && req.getAttribute("org.apache.tomcat.comet.support") == Boolean.TRUE) {
-                    comet = true;
-                    res.action(ActionCode.ACTION_COMET_BEGIN, null);
+                if (request.isComet()) {
+                    if (!response.isClosed()) {
+                        comet = true;
+                        res.action(ActionCode.ACTION_COMET_BEGIN, null);
+                    } else {
+                        // Clear the filter chain, as otherwise it will not be reset elsewhere
+                        // since this is a Comet request
+                        request.setFilterChain(null);
+                    }
                 }
 
             }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java Tue Sep 12 17:55:15 2006
@@ -195,8 +195,20 @@
      */
     protected String authType = null;
 
+    
+    /**
+     * Associated event.
+     */
+    protected CometEventImpl event = null;
+    
 
     /**
+     * Comet state
+     */
+    protected boolean comet = false;
+    
+    
+    /**
      * The current dispatcher type.
      */
     protected Object dispatcherType = null;
@@ -373,6 +385,12 @@
         dispatcherType = null;
         requestDispatcherPath = null;
 
+        comet = false;
+        if (event != null) {
+            event.clear();
+            event = null;
+        }
+        
         authType = null;
         inputBuffer.recycle();
         usingInputStream = false;
@@ -2193,6 +2211,34 @@
     }
 
 
+    /**
+     * Get the event associated with the request.
+     * @return
+     */
+    public CometEventImpl getEvent() {
+        if (event == null) {
+            event = new CometEventImpl(this, response);
+        }
+        return event;
+    }
+    
+    
+    /**
+     * Return true if the current request is handling Comet traffic.
+     */
+    public boolean isComet() {
+        return comet;
+    }
+
+    
+    /**
+     * Set comet state.
+     */
+    public void setComet(boolean comet) {
+        this.comet = comet;
+    }
+
+    
     // ------------------------------------------------------ Protected Methods
 
 
@@ -2545,6 +2591,5 @@
         }
 
     }
-
 
 }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java Tue Sep 12 17:55:15 2006
@@ -481,13 +481,7 @@
     public void finishResponse() 
         throws IOException {
         // Writing leftover bytes
-        try {
-            outputBuffer.close();
-        } catch(IOException e) {
-	    ;
-        } catch(Throwable t) {
-	    t.printStackTrace();
-        }
+        outputBuffer.close();
     }
 
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java Tue Sep 12 17:55:15 2006
@@ -31,6 +31,10 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.CometEvent;
+import org.apache.catalina.CometFilter;
+import org.apache.catalina.CometFilterChain;
+import org.apache.catalina.CometProcessor;
 import org.apache.catalina.InstanceEvent;
 import org.apache.catalina.security.SecurityUtil;
 import org.apache.catalina.util.InstanceSupport;
@@ -47,7 +51,7 @@
  * @version $Revision: 303523 $ $Date: 2004-11-22 17:35:18 +0100 (lun., 22 nov. 2004) $
  */
 
-final class ApplicationFilterChain implements FilterChain {
+final class ApplicationFilterChain implements FilterChain, CometFilterChain {
 
 
     // -------------------------------------------------------------- Constants
@@ -114,7 +118,7 @@
     
     /**
      * Static class array used when the SecurityManager is turned on and 
-     * <code>doFilter</code is invoked.
+     * <code>doFilter</code> is invoked.
      */
     private static Class[] classType = new Class[]{ServletRequest.class, 
                                                    ServletResponse.class,
@@ -122,12 +126,26 @@
                                                    
     /**
      * Static class array used when the SecurityManager is turned on and 
-     * <code>service</code is invoked.
+     * <code>service</code> is invoked.
      */                                                 
     private static Class[] classTypeUsedInService = new Class[]{
                                                          ServletRequest.class,
                                                          ServletResponse.class};
 
+    /**
+     * Static class array used when the SecurityManager is turned on and 
+     * <code>doFilterEvent</code> is invoked.
+     */
+    private static Class[] cometClassType = 
+        new Class[]{ CometEvent.class, CometFilterChain.class};
+                                                   
+    /**
+     * Static class array used when the SecurityManager is turned on and 
+     * <code>event</code> is invoked.
+     */                                                 
+    private static Class[] classTypeUsedInEvent = 
+        new Class[] { CometEvent.class };
+
     // ---------------------------------------------------- FilterChain Methods
 
 
@@ -279,6 +297,163 @@
     }
 
 
+    /**
+     * Invoke the next filter in this chain, passing the specified request
+     * and response.  If there are no more filters in this chain, invoke
+     * the <code>service()</code> method of the servlet itself.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void doFilterEvent(CometEvent event)
+        throws IOException, ServletException {
+
+        if( System.getSecurityManager() != null ) {
+            final CometEvent ev = event;
+            try {
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedExceptionAction() {
+                        public Object run() 
+                            throws ServletException, IOException {
+                            internalDoFilterEvent(ev);
+                            return null;
+                        }
+                    }
+                );
+            } catch( PrivilegedActionException pe) {
+                Exception e = pe.getException();
+                if (e instanceof ServletException)
+                    throw (ServletException) e;
+                else if (e instanceof IOException)
+                    throw (IOException) e;
+                else if (e instanceof RuntimeException)
+                    throw (RuntimeException) e;
+                else
+                    throw new ServletException(e.getMessage(), e);
+            }
+        } else {
+            internalDoFilterEvent(event);
+        }
+    }
+
+    private void internalDoFilterEvent(CometEvent event)
+        throws IOException, ServletException {
+
+        // Call the next filter if there is one
+        if (pos < n) {
+            ApplicationFilterConfig filterConfig = filters[pos++];
+            CometFilter filter = null;
+            try {
+                filter = (CometFilter) filterConfig.getFilter();
+                // FIXME: No instance listener processing for events for now
+                /*
+                support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
+                        filter, event);
+                        */
+
+                if( System.getSecurityManager() != null ) {
+                    final CometEvent ev = event;
+                    Principal principal = 
+                        ev.getHttpServletRequest().getUserPrincipal();
+
+                    Object[] args = new Object[]{ev, this};
+                    SecurityUtil.doAsPrivilege
+                        ("doFilterEvent", (Filter) filter, cometClassType, args);
+
+                    args = null;
+                } else {  
+                    filter.doFilterEvent(event, this);
+                }
+
+                /*support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+                        filter, event);*/
+            } catch (IOException e) {
+                /*
+                if (filter != null)
+                    support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+                            filter, event, e);
+                            */
+                throw e;
+            } catch (ServletException e) {
+                /*
+                if (filter != null)
+                    support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+                            filter, event, e);
+                            */
+                throw e;
+            } catch (RuntimeException e) {
+                /*
+                if (filter != null)
+                    support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+                            filter, event, e);
+                            */
+                throw e;
+            } catch (Throwable e) {
+                /*if (filter != null)
+                    support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+                            filter, event, e);*/
+                throw new ServletException
+                    (sm.getString("filterChain.filter"), e);
+            }
+            return;
+        }
+
+        // We fell off the end of the chain -- call the servlet instance
+        try {
+            /*
+            support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
+                    servlet, request, response);
+                    */
+            if( System.getSecurityManager() != null ) {
+                final CometEvent ev = event;
+                Principal principal = 
+                    ev.getHttpServletRequest().getUserPrincipal();
+                Object[] args = new Object[]{ ev };
+                SecurityUtil.doAsPrivilege("event",
+                        servlet,
+                        classTypeUsedInEvent, 
+                        args,
+                        principal);
+                args = null;
+            } else {  
+                ((CometProcessor) servlet).event(event);
+            }
+            /*
+            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+                    servlet, request, response);*/
+        } catch (IOException e) {
+            /*
+            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+                    servlet, request, response, e);
+                    */
+            throw e;
+        } catch (ServletException e) {
+            /*
+            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+                    servlet, request, response, e);
+                    */
+            throw e;
+        } catch (RuntimeException e) {
+            /*
+            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+                    servlet, request, response, e);
+                    */
+            throw e;
+        } catch (Throwable e) {
+            /*
+            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+                    servlet, request, response, e);
+                    */
+            throw new ServletException
+                (sm.getString("filterChain.servlet"), e);
+        }
+
+    }
+
+
     // -------------------------------------------------------- Package Methods
 
 
@@ -311,6 +486,14 @@
         servlet = null;
         support = null;
 
+    }
+
+
+    /**
+     * Prepare for reuse of the filters and wrapper executed by this chain.
+     */
+    void reuse() {
+        pos = 0;
     }
 
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java Tue Sep 12 17:55:15 2006
@@ -22,6 +22,7 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.catalina.CometFilter;
 import org.apache.catalina.Globals;
 import org.apache.catalina.Wrapper;
 import org.apache.catalina.connector.Request;
@@ -118,6 +119,8 @@
         if (servlet == null)
             return (null);
 
+        boolean comet = false;
+        
         // Create and initialize a filter chain object
         ApplicationFilterChain filterChain = null;
         if ((securityManager == null) && (request instanceof Request)) {
@@ -127,6 +130,7 @@
                 filterChain = new ApplicationFilterChain();
                 req.setFilterChain(filterChain);
             }
+            comet = req.isComet();
         } else {
             // Security: Do not recycle
             filterChain = new ApplicationFilterChain();
@@ -148,8 +152,6 @@
         // Acquire the information we will need to match filter mappings
         String servletName = wrapper.getName();
 
-        int n = 0;
-
         // Add the relevant path-mapped filters to this filter chain
         for (int i = 0; i < filterMaps.length; i++) {
             if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
@@ -163,8 +165,21 @@
                 ;       // FIXME - log configuration problem
                 continue;
             }
-            filterChain.addFilter(filterConfig);
-            n++;
+            boolean isCometFilter = false;
+            if (comet) {
+                try {
+                    isCometFilter = filterConfig.getFilter() instanceof CometFilter;
+                } catch (Exception e) {
+                    // Note: The try catch is there because getFilter has a lot of 
+                    // declared exceptions. However, the filter is allocated much
+                    // earlier
+                }
+                if (isCometFilter) {
+                    filterChain.addFilter(filterConfig);
+                }
+            } else {
+                filterChain.addFilter(filterConfig);
+            }
         }
 
         // Add filters that match on servlet name second
@@ -180,8 +195,21 @@
                 ;       // FIXME - log configuration problem
                 continue;
             }
-            filterChain.addFilter(filterConfig);
-            n++;
+            boolean isCometFilter = false;
+            if (comet) {
+                try {
+                    isCometFilter = filterConfig.getFilter() instanceof CometFilter;
+                } catch (Exception e) {
+                    // Note: The try catch is there because getFilter has a lot of 
+                    // declared exceptions. However, the filter is allocated much
+                    // earlier
+                }
+                if (isCometFilter) {
+                    filterChain.addFilter(filterConfig);
+                }
+            } else {
+                filterChain.addFilter(filterConfig);
+            }
         }
 
         // Return the completed filter chain

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Tue Sep 12 17:55:15 2006
@@ -4473,15 +4473,15 @@
 
         try {
 
-            // Stop our filters
-            filterStop();
-
             // Stop our child containers, if any
             Container[] children = findChildren();
             for (int i = 0; i < children.length; i++) {
                 if (children[i] instanceof Lifecycle)
                     ((Lifecycle) children[i]).stop();
             }
+
+            // Stop our filters
+            filterStop();
 
             // Stop our application listeners
             listenerStop();

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java Tue Sep 12 17:55:15 2006
@@ -26,6 +26,7 @@
 import javax.servlet.ServletRequestListener;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.CometEvent;
 import org.apache.catalina.Container;
 import org.apache.catalina.Globals;
 import org.apache.catalina.Wrapper;
@@ -33,8 +34,6 @@
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.util.StringManager;
 import org.apache.catalina.valves.ValveBase;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.tomcat.util.buf.MessageBytes;
 
 /**
@@ -69,9 +68,6 @@
         StringManager.getManager(Constants.Package);
 
 
-    private static Log log = LogFactory.getLog(StandardContextValve.class);
-
-    
     private StandardContext context = null;
     
 
@@ -198,6 +194,85 @@
             }
         }
                 
+    }
+
+
+    /**
+     * Select the appropriate child Wrapper to process this request,
+     * based on the specified request URI.  If no matching Wrapper can
+     * be found, return an appropriate HTTP error.
+     *
+     * @param request Request to be processed
+     * @param response Response to be produced
+     * @param valveContext Valve context used to forward to the next Valve
+     *
+     * @exception IOException if an input/output error occurred
+     * @exception ServletException if a servlet error occurred
+     */
+    public final void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException {
+
+        // Select the Wrapper to be used for this Request
+        Wrapper wrapper = request.getWrapper();
+
+        // Normal request processing
+        // FIXME: This could be an addition to the core API too
+        /*
+        Object instances[] = context.getApplicationEventListeners();
+
+        ServletRequestEvent event = null;
+
+        if ((instances != null) 
+                && (instances.length > 0)) {
+            event = new ServletRequestEvent
+                (((StandardContext) container).getServletContext(), 
+                 request.getRequest());
+            // create pre-service event
+            for (int i = 0; i < instances.length; i++) {
+                if (instances[i] == null)
+                    continue;
+                if (!(instances[i] instanceof ServletRequestListener))
+                    continue;
+                ServletRequestListener listener =
+                    (ServletRequestListener) instances[i];
+                try {
+                    listener.requestInitialized(event);
+                } catch (Throwable t) {
+                    container.getLogger().error(sm.getString("requestListenerValve.requestInit",
+                                     instances[i].getClass().getName()), t);
+                    ServletRequest sreq = request.getRequest();
+                    sreq.setAttribute(Globals.EXCEPTION_ATTR,t);
+                    return;
+                }
+            }
+        }
+        */
+
+        wrapper.getPipeline().getFirst().event(request, response, event);
+
+        /*
+        if ((instances !=null ) &&
+                (instances.length > 0)) {
+            // create post-service event
+            for (int i = 0; i < instances.length; i++) {
+                if (instances[i] == null)
+                    continue;
+                if (!(instances[i] instanceof ServletRequestListener))
+                    continue;
+                ServletRequestListener listener =
+                    (ServletRequestListener) instances[i];
+                try {
+                    listener.requestDestroyed(event);
+                } catch (Throwable t) {
+                    container.getLogger().error(sm.getString("requestListenerValve.requestDestroy",
+                                     instances[i].getClass().getName()), t);
+                    ServletRequest sreq = request.getRequest();
+                    sreq.setAttribute(Globals.EXCEPTION_ATTR,t);
+                }
+            }
+        }
+        */
+      
     }
 
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java Tue Sep 12 17:55:15 2006
@@ -23,6 +23,7 @@
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.CometEvent;
 import org.apache.catalina.Host;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
@@ -105,6 +106,25 @@
 
         // Ask this Host to process this request
         host.getPipeline().getFirst().invoke(request, response);
+
+    }
+
+
+    /**
+     * Process Comet event.
+     *
+     * @param request Request to be processed
+     * @param response Response to be produced
+     * @param valveContext Valve context used to forward to the next Valve
+     *
+     * @exception IOException if an input/output error occurred
+     * @exception ServletException if a servlet error occurred
+     */
+    public final void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException {
+
+        // Ask this Host to process this request
+        request.getHost().getPipeline().getFirst().event(request, response, event);
 
     }
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java Tue Sep 12 17:55:15 2006
@@ -25,6 +25,7 @@
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.CometEvent;
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
 import org.apache.catalina.Wrapper;
@@ -124,6 +125,57 @@
 
         // Ask this Context to process this request
         context.getPipeline().getFirst().invoke(request, response);
+
+        // Access a session (if present) to update last accessed time, based on a
+        // strict interpretation of the specification
+        if (Globals.STRICT_SERVLET_COMPLIANCE) {
+            request.getSession(false);
+        }
+
+        // Error page processing
+        response.setSuspended(false);
+
+        Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
+
+        if (t != null) {
+            throwable(request, response, t);
+        } else {
+            status(request, response);
+        }
+
+        // Restore the context classloader
+        Thread.currentThread().setContextClassLoader
+            (StandardHostValve.class.getClassLoader());
+
+    }
+
+
+    /**
+     * Process Comet event.
+     *
+     * @param request Request to be processed
+     * @param response Response to be produced
+     * @param valveContext Valve context used to forward to the next Valve
+     *
+     * @exception IOException if an input/output error occurred
+     * @exception ServletException if a servlet error occurred
+     */
+    public final void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException {
+
+        // Select the Context to be used for this Request
+        Context context = request.getContext();
+
+        // Bind the context CL to the current thread
+        if( context.getLoader() != null ) {
+            // Not started - it should check for availability first
+            // This should eventually move to Engine, it's generic.
+            Thread.currentThread().setContextClassLoader
+                    (context.getLoader().getClassLoader());
+        }
+
+        // Ask this Context to process this request
+        context.getPipeline().getFirst().event(request, response, event);
 
         // Access a session (if present) to update last accessed time, based on a
         // strict interpretation of the specification

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java Tue Sep 12 17:55:15 2006
@@ -27,6 +27,8 @@
 import javax.servlet.UnavailableException;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.catalina.CometEvent;
+import org.apache.catalina.CometProcessor;
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
 import org.apache.catalina.connector.ClientAbortException;
@@ -155,6 +157,12 @@
             servlet = null;
         }
 
+        // Identify if the request is Comet related now that the servlet has been allocated
+        if (servlet instanceof CometProcessor 
+                && request.getAttribute("org.apache.tomcat.comet.support") == Boolean.TRUE) {
+            request.setComet(true);
+        }
+        
         // Acknowlege the request
         try {
             response.sendAcknowledgement();
@@ -196,13 +204,16 @@
             else
             	request.removeAttribute(Globals.JSP_FILE_ATTR);
             if ((servlet != null) && (filterChain != null)) {
-
                 // Swallow output if needed
                 if (context.getSwallowOutput()) {
                     try {
                         SystemLogHandler.startCapture();
-                        filterChain.doFilter(request.getRequest(), 
-                                response.getResponse());
+                        if (request.isComet()) {
+                            filterChain.doFilterEvent(request.getEvent());
+                        } else {
+                            filterChain.doFilter(request.getRequest(), 
+                                    response.getResponse());
+                        }
                     } finally {
                         String log = SystemLogHandler.stopCapture();
                         if (log != null && log.length() > 0) {
@@ -210,8 +221,12 @@
                         }
                     }
                 } else {
-                    filterChain.doFilter
-                        (request.getRequest(), response.getResponse());
+                    if (request.isComet()) {
+                        filterChain.doFilterEvent(request.getEvent());
+                    } else {
+                        filterChain.doFilter
+                            (request.getRequest(), response.getResponse());
+                    }
                 }
 
             }
@@ -264,11 +279,23 @@
         }
 
         // Release the filter chain (if any) for this request
-        try {
-            if (filterChain != null)
+        if (filterChain != null) {
+            if (request.isComet()) {
+                // If this is a Comet request, then the same chain will be used for the
+                // processing of all subsequent events.
+                filterChain.reuse();
+            } else {
                 filterChain.release();
+            }
+        }
+
+        // Deallocate the allocated servlet instance
+        try {
+            if (servlet != null) {
+                wrapper.deallocate(servlet);
+            }
         } catch (Throwable e) {
-            container.getLogger().error(sm.getString("standardWrapper.releaseFilters",
+            container.getLogger().error(sm.getString("standardWrapper.deallocateException",
                              wrapper.getName()), e);
             if (throwable == null) {
                 throwable = e;
@@ -276,6 +303,159 @@
             }
         }
 
+        // If this servlet has been marked permanently unavailable,
+        // unload it and release this instance
+        try {
+            if ((servlet != null) &&
+                (wrapper.getAvailable() == Long.MAX_VALUE)) {
+                wrapper.unload();
+            }
+        } catch (Throwable e) {
+            container.getLogger().error(sm.getString("standardWrapper.unloadException",
+                             wrapper.getName()), e);
+            if (throwable == null) {
+                throwable = e;
+                exception(request, response, e);
+            }
+        }
+        long t2=System.currentTimeMillis();
+
+        long time=t2-t1;
+        processingTime += time;
+        if( time > maxTime) maxTime=time;
+        if( time < minTime) minTime=time;
+
+    }
+
+
+    /**
+     * Process a Comet event. The main differences here are to not use sendError
+     * (the response is committed), to avoid creating a new filter chain
+     * (which would work but be pointless), and a few very minor tweaks. 
+     *
+     * @param request The servlet request to be processed
+     * @param response The servlet response to be created
+     *
+     * @exception IOException if an input/output error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     * @exception ServletException if a servlet error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     */
+    public void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException {
+        
+        // Initialize local variables we may need
+        Throwable throwable = null;
+        // This should be a Request attribute...
+        long t1=System.currentTimeMillis();
+        // FIXME: Add a flag to count the total amount of events processed ? requestCount++;
+        StandardWrapper wrapper = (StandardWrapper) getContainer();
+        Servlet servlet = null;
+        Context context = (Context) wrapper.getParent();
+
+        // Check for the application being marked unavailable
+        boolean unavailable = !context.getAvailable() || wrapper.isUnavailable();
+        
+        // Allocate a servlet instance to process this request
+        try {
+            if (!unavailable) {
+                servlet = wrapper.allocate();
+            }
+        } catch (UnavailableException e) {
+            // The response is already committed, so it's not possible to do anything
+        } catch (ServletException e) {
+            container.getLogger().error(sm.getString("standardWrapper.allocateException",
+                             wrapper.getName()), StandardWrapper.getRootCause(e));
+            throwable = e;
+            exception(request, response, e);
+            servlet = null;
+        } catch (Throwable e) {
+            container.getLogger().error(sm.getString("standardWrapper.allocateException",
+                             wrapper.getName()), e);
+            throwable = e;
+            exception(request, response, e);
+            servlet = null;
+        }
+
+        MessageBytes requestPathMB = null;
+        if (request != null) {
+            requestPathMB = request.getRequestPathMB();
+        }
+        request.setAttribute
+            (ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
+             ApplicationFilterFactory.REQUEST_INTEGER);
+        request.setAttribute
+            (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
+             requestPathMB);
+        // Get the current (unchanged) filter chain for this request
+        ApplicationFilterChain filterChain = 
+            (ApplicationFilterChain) request.getFilterChain();
+
+        // Call the filter chain for this request
+        // NOTE: This also calls the servlet's event() method
+        try {
+            String jspFile = wrapper.getJspFile();
+            if (jspFile != null)
+                request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
+            else
+                request.removeAttribute(Globals.JSP_FILE_ATTR);
+            if ((servlet != null) && (filterChain != null)) {
+
+                // Swallow output if needed
+                if (context.getSwallowOutput()) {
+                    try {
+                        SystemLogHandler.startCapture();
+                        filterChain.doFilterEvent(request.getEvent());
+                    } finally {
+                        String log = SystemLogHandler.stopCapture();
+                        if (log != null && log.length() > 0) {
+                            context.getLogger().info(log);
+                        }
+                    }
+                } else {
+                    filterChain.doFilterEvent(request.getEvent());
+                }
+
+            }
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+        } catch (ClientAbortException e) {
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+            throwable = e;
+            exception(request, response, e);
+        } catch (IOException e) {
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+            container.getLogger().warn(sm.getString("standardWrapper.serviceException",
+                             wrapper.getName()), e);
+            throwable = e;
+            exception(request, response, e);
+        } catch (UnavailableException e) {
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+            container.getLogger().warn(sm.getString("standardWrapper.serviceException",
+                             wrapper.getName()), e);
+            // Do not save exception in 'throwable', because we
+            // do not want to do exception(request, response, e) processing
+        } catch (ServletException e) {
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+            Throwable rootCause = StandardWrapper.getRootCause(e);
+            if (!(rootCause instanceof ClientAbortException)) {
+                container.getLogger().error(sm.getString("standardWrapper.serviceException",
+                                 wrapper.getName()), rootCause);
+            }
+            throwable = e;
+            exception(request, response, e);
+        } catch (Throwable e) {
+            request.removeAttribute(Globals.JSP_FILE_ATTR);
+            container.getLogger().error(sm.getString("standardWrapper.serviceException",
+                             wrapper.getName()), e);
+            throwable = e;
+            exception(request, response, e);
+        }
+
+        // Release the filter chain (if any) for this request
+        if (filterChain != null) {
+            filterChain.reuse();
+        }
+
         // Deallocate the allocated servlet instance
         try {
             if (servlet != null) {
@@ -305,6 +485,7 @@
                 exception(request, response, e);
             }
         }
+
         long t2=System.currentTimeMillis();
 
         long time=t2-t1;

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java Tue Sep 12 17:55:15 2006
@@ -26,6 +26,7 @@
 import javax.management.ObjectName;
 import javax.servlet.ServletException;
 
+import org.apache.catalina.CometEvent;
 import org.apache.catalina.Contained;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
@@ -177,6 +178,26 @@
      */
     public abstract void invoke(Request request, Response response)
         throws IOException, ServletException;
+
+
+    /**
+     * Process a Comet event. This method will rarely need to be provided by
+     * a subclass, unless it needs to reassociate a particular object with 
+     * the thread that is processing the request.
+     *
+     * @param request The servlet request to be processed
+     * @param response The servlet response to be created
+     *
+     * @exception IOException if an input/output error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     * @exception ServletException if a servlet error occurs, or is thrown
+     *  by a subsequently invoked Valve, Filter, or Servlet
+     */
+    public void event(Request request, Response response, CometEvent event)
+        throws IOException, ServletException {
+        // Perform the request
+        getNext().event(request, response, event);
+    }
 
 
     /**



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