Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49528
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 4 Jul 2010 20:38:41 +0000 (20:38 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 4 Jul 2010 20:38:41 +0000 (20:38 +0000)
AsyncContext.start() uses an internal dispatch but this should not have the same side-effects as calling dispatch()
TCK and test cases passes with this patch

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@960392 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/AsyncContextImpl.java
webapps/docs/changelog.xml

index b3c800f..04c94ea 100644 (file)
@@ -48,7 +48,8 @@ import org.apache.juli.logging.LogFactory;
 public class AsyncContextImpl implements AsyncContext {
     
     public static enum AsyncState {
-        NOT_STARTED, STARTED, DISPATCHING, DISPATCHED, COMPLETING, TIMING_OUT, ERROR_DISPATCHING
+        NOT_STARTED, STARTED, DISPATCHING, DISPATCHING_INTERNAL, DISPATCHED,
+        COMPLETING, TIMING_OUT, ERROR_DISPATCHING
     }
     
     private static final Log log = LogFactory.getLog(AsyncContextImpl.class);
@@ -178,8 +179,8 @@ public class AsyncContextImpl implements AsyncContext {
             log.debug("AsyncContext Start Called["+state.get()+"; "+request.getRequestURI()+"?"+request.getQueryString()+"]", new DebugException());
         }
 
-        if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING) ||
-            state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING)) {
+        if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING_INTERNAL) ||
+            state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING_INTERNAL)) {
             // TODO SERVLET3 - async
             final ServletContext sctx = getServletRequest().getServletContext();
             Runnable r = new Runnable() {
@@ -333,6 +334,20 @@ public class AsyncContextImpl implements AsyncContext {
                     dispatch = null;
                 }
             }
+        } else if (this.state.get() == AsyncState.DISPATCHING_INTERNAL) {
+            if (this.dispatch!=null) {
+                try {
+                    dispatch.run();
+                } catch (RuntimeException x) {
+                    doInternalComplete(true);
+                    if (x.getCause() instanceof ServletException) throw (ServletException)x.getCause();
+                    if (x.getCause() instanceof IOException) throw (IOException)x.getCause();
+                    else throw new ServletException(x);
+                } finally {
+                    dispatch = null;
+                    this.state.set(AsyncState.DISPATCHED);
+                }
+            }
         } else if (this.state.get()==AsyncState.COMPLETING) {
             doInternalComplete(false);
         } else {
index a78bc25..e948827 100644 (file)
         rather than an empty string. (markt)
       </fix>
       <fix>
+        <bug>49528</bug>: Ensure AsyncContext.isAsyncStarted() returns the
+        correct value after AsyncContext.start(). Tomcat implements this
+        using an internal dispatch that requires slightly different treatment
+        from a standard dispatch to ensure the correct value is returned.
+        (markt)
+      </fix>
+      <fix>
         <bug>49530</bug>: Contexts and Servlets not stopped when Tomcat is shut
         down. (markt)
       </fix>