You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2010/07/05 22:51:21 UTC

svn commit: r960692 - in /tomcat/trunk: java/org/apache/catalina/connector/Request.java java/org/apache/catalina/core/AsyncContextImpl.java test/org/apache/catalina/core/TestAsyncContextImpl.java

Author: markt
Date: Mon Jul  5 20:51:21 2010
New Revision: 960692

URL: http://svn.apache.org/viewvc?rev=960692&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49528
Previous fix was incomplete. Improve test case and fix
TCK and test cases pass with this patch

Modified:
    tomcat/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=960692&r1=960691&r2=960692&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Mon Jul  5 20:51:21 2010
@@ -1578,6 +1578,7 @@ public class Request
         }
         
         return (asyncContext.getState()==AsyncContextImpl.AsyncState.DISPATCHING ||
+                asyncContext.getState()==AsyncContextImpl.AsyncState.DISPATCHING_RUNNABLE  ||
                 asyncContext.getState()==AsyncContextImpl.AsyncState.TIMING_OUT  ||
                 asyncContext.getState()==AsyncContextImpl.AsyncState.STARTED     ||
                 asyncContext.getState()==AsyncContextImpl.AsyncState.ERROR_DISPATCHING ||

Modified: tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=960692&r1=960691&r2=960692&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Mon Jul  5 20:51:21 2010
@@ -48,8 +48,8 @@ import org.apache.juli.logging.LogFactor
 public class AsyncContextImpl implements AsyncContext {
     
     public static enum AsyncState {
-        NOT_STARTED, STARTED, DISPATCHING, DISPATCHING_INTERNAL, DISPATCHED,
-        COMPLETING, TIMING_OUT, ERROR_DISPATCHING
+        NOT_STARTED, STARTED, DISPATCHING, DISPATCHING_RUNNABLE, DISPATCHED,
+        COMPLETING, COMPLETING_RUNNABLE, TIMING_OUT, ERROR_DISPATCHING
     }
     
     private static final Log log = LogFactory.getLog(AsyncContextImpl.class);
@@ -87,6 +87,9 @@ public class AsyncContextImpl implements
             AtomicBoolean dispatched = new AtomicBoolean(false);
             request.getCoyoteRequest().action(ActionCode.ACTION_ASYNC_COMPLETE,dispatched);
             if (!dispatched.get()) doInternalComplete(false);
+        } else if (state.compareAndSet(AsyncState.DISPATCHING_RUNNABLE,
+                AsyncState.COMPLETING_RUNNABLE)) {
+            // do nothing
         } else {
             throw new IllegalStateException("Complete not allowed. Invalid state:"+state.get());
         }
@@ -179,8 +182,8 @@ public class AsyncContextImpl implements
             log.debug("AsyncContext Start Called["+state.get()+"; "+request.getRequestURI()+"?"+request.getQueryString()+"]", new DebugException());
         }
 
-        if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING_INTERNAL) ||
-            state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING_INTERNAL)) {
+        if (state.compareAndSet(AsyncState.STARTED, AsyncState.DISPATCHING_RUNNABLE) ||
+            state.compareAndSet(AsyncState.DISPATCHED, AsyncState.DISPATCHING_RUNNABLE)) {
             // TODO SERVLET3 - async
             final ServletContext sctx = getServletRequest().getServletContext();
             Runnable r = new Runnable() {
@@ -254,7 +257,9 @@ public class AsyncContextImpl implements
     }
 
     public boolean isStarted() {
-        return (state.get() == AsyncState.STARTED || state.get() == AsyncState.DISPATCHING);
+        return (state.get() == AsyncState.STARTED ||
+                state.get() == AsyncState.DISPATCHING ||
+                state.get() == AsyncState.DISPATCHING_RUNNABLE);
     }
 
     public void setStarted(Context context) {
@@ -334,7 +339,7 @@ public class AsyncContextImpl implements
                     dispatch = null;
                 }
             }
-        } else if (this.state.get() == AsyncState.DISPATCHING_INTERNAL) {
+        } else if (this.state.get() == AsyncState.DISPATCHING_RUNNABLE) {
             if (this.dispatch!=null) {
                 try {
                     dispatch.run();
@@ -345,7 +350,14 @@ public class AsyncContextImpl implements
                     else throw new ServletException(x);
                 } finally {
                     dispatch = null;
-                    this.state.set(AsyncState.DISPATCHED);
+                }
+                if (this.state.compareAndSet(AsyncState.COMPLETING_RUNNABLE,
+                        AsyncState.COMPLETING)) {
+                    doInternalComplete(false);
+                } else if (this.state.get() == AsyncState.DISPATCHING_RUNNABLE) {
+                    doInternalComplete(true);
+                    throw new IllegalStateException(
+                            "Failed to call dispatch() or complete() after start()");
                 }
             }
         } else if (this.state.get()==AsyncState.COMPLETING) {

Modified: tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=960692&r1=960691&r2=960692&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Mon Jul  5 20:51:21 2010
@@ -50,17 +50,17 @@ public class TestAsyncContextImpl extend
         // Call the servlet once
         getUrl("http://localhost:" + getPort() + "/");
 
-        assertEquals("", servlet.getErrors());
+        assertEquals("1false2true3true4true5false", servlet.getResult());
     }
     
     private static class Bug49528Servlet extends HttpServlet {
 
         private static final long serialVersionUID = 1L;
         
-        private StringBuilder errors = new StringBuilder();
+        private StringBuilder result = new StringBuilder();
         
-        public String getErrors() {
-            return errors.toString();
+        public String getResult() {
+            return result.toString();
         }
 
         @Override
@@ -68,19 +68,24 @@ public class TestAsyncContextImpl extend
                 final HttpServletResponse resp)
                 throws ServletException, IOException {
             
-            confirmFalse("1", req);
+            result.append('1');
+            result.append(req.isAsyncStarted());
             req.startAsync();
-            confirmTrue("2", req);
+            result.append('2');
+            result.append(req.isAsyncStarted());
             
             req.getAsyncContext().start(new Runnable() {
                 @Override
                 public void run() {
                     try {
-                        confirmTrue("3", req);
+                        result.append('3');
+                        result.append(req.isAsyncStarted());
                         Thread.sleep(1000);
-                        confirmTrue("4", req);
+                        result.append('4');
+                        result.append(req.isAsyncStarted());
                         req.getAsyncContext().complete();
-                        confirmFalse("5", req);
+                        result.append('5');
+                        result.append(req.isAsyncStarted());
                     } catch (InterruptedException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
@@ -91,20 +96,5 @@ public class TestAsyncContextImpl extend
             // when debugging
             req.getMethod();
         }
-        
-        private void confirmFalse(String stage, HttpServletRequest req) {
-            if (req.isAsyncStarted()) {
-                errors.append("Stage " + stage +
-                        ": Async started when not expected\n");
-            }
-        }
-
-        private void confirmTrue(String stage, HttpServletRequest req) {
-            if (!req.isAsyncStarted()) {
-                errors.append("Stage " + stage +
-                        ": Async not started when expected\n");
-            }
-        }
-
     }
 }



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