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 2015/06/16 15:04:12 UTC

svn commit: r1685816 - in /tomcat/trunk: java/org/apache/catalina/connector/InputBuffer.java java/org/apache/coyote/Response.java test/org/apache/catalina/connector/TestCoyoteOutputStream.java

Author: markt
Date: Tue Jun 16 13:04:11 2015
New Revision: 1685816

URL: http://svn.apache.org/r1685816
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57944
Ensure that if either or both of the non-blocking listeners are set on non-container threads that the appropriate events are triggered.

Modified:
    tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java
    tomcat/trunk/java/org/apache/coyote/Response.java
    tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java?rev=1685816&r1=1685815&r2=1685816&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java Tue Jun 16 13:04:11 2015
@@ -260,6 +260,10 @@ public class InputBuffer extends Reader
         // is not required.
         if (!coyoteRequest.isFinished() && isReady()) {
             coyoteRequest.action(ActionCode.DISPATCH_READ, null);
+            if (!ContainerThreadMarker.isContainerThread()) {
+                // Not on a container thread so need to execute the dispatch
+                coyoteRequest.action(ActionCode.DISPATCH_EXECUTE, null);
+            }
         }
     }
 

Modified: tomcat/trunk/java/org/apache/coyote/Response.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1685816&r1=1685815&r2=1685816&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/Response.java (original)
+++ tomcat/trunk/java/org/apache/coyote/Response.java Tue Jun 16 13:04:11 2015
@@ -581,7 +581,6 @@ public final class Response {
         // the container will call listener.onWritePossible() once data can be
         // written.
         if (isReady()) {
-            action(ActionCode.DISPATCH_WRITE, null);
             synchronized (nonBlockingStateLock) {
                 // Ensure we don't get multiple write registrations if
                 // ServletOutputStream.isReady() returns false during a call to
@@ -592,6 +591,11 @@ public final class Response {
                 // happen
                 fireListener = true;
             }
+            action(ActionCode.DISPATCH_WRITE, null);
+            if (!ContainerThreadMarker.isContainerThread()) {
+                // Not on a container thread so need to execute the dispatch
+                action(ActionCode.DISPATCH_EXECUTE, null);
+            }
         }
     }
 

Modified: tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java?rev=1685816&r1=1685815&r2=1685816&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java (original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java Tue Jun 16 13:04:11 2015
@@ -40,43 +40,73 @@ import org.apache.tomcat.util.buf.ByteCh
 public class TestCoyoteOutputStream extends TomcatBaseTest {
 
     @Test
-    public void testNonBlockingWriteNoneBlockingWriteNone() throws Exception {
-        doNonBlockingTest(0, 0);
+    public void testNonBlockingWriteNoneBlockingWriteNoneContainerThread() throws Exception {
+        doNonBlockingTest(0, 0, true);
     }
 
     @Test
-    public void testNonBlockingWriteOnceBlockingWriteNone() throws Exception {
-        doNonBlockingTest(1, 0);
+    public void testNonBlockingWriteOnceBlockingWriteNoneContainerThread() throws Exception {
+        doNonBlockingTest(1, 0, true);
     }
 
     @Test
-    public void testNonBlockingWriteTwiceBlockingWriteNone() throws Exception {
-        doNonBlockingTest(2, 0);
+    public void testNonBlockingWriteTwiceBlockingWriteNoneContainerThread() throws Exception {
+        doNonBlockingTest(2, 0, true);
     }
 
     @Test
-    public void testNonBlockingWriteNoneBlockingWriteOnce() throws Exception {
-        doNonBlockingTest(0, 1);
+    public void testNonBlockingWriteNoneBlockingWriteOnceContainerThread() throws Exception {
+        doNonBlockingTest(0, 1, true);
     }
 
     @Test
-    public void testNonBlockingWriteOnceBlockingWriteOnce() throws Exception {
-        doNonBlockingTest(1, 1);
+    public void testNonBlockingWriteOnceBlockingWriteOnceContainerThread() throws Exception {
+        doNonBlockingTest(1, 1, true);
     }
 
     @Test
-    public void testNonBlockingWriteTwiceBlockingWriteOnce() throws Exception {
-        doNonBlockingTest(2, 1);
+    public void testNonBlockingWriteTwiceBlockingWriteOnceContainerThread() throws Exception {
+        doNonBlockingTest(2, 1, true);
     }
 
-    private void doNonBlockingTest(int asyncWriteTarget, int syncWriteTarget)
-            throws Exception {
+    @Test
+    public void testNonBlockingWriteNoneBlockingWriteNoneNonContainerThread() throws Exception {
+        doNonBlockingTest(0, 0, false);
+    }
+
+    @Test
+    public void testNonBlockingWriteOnceBlockingWriteNoneNonContainerThread() throws Exception {
+        doNonBlockingTest(1, 0, false);
+    }
+
+    @Test
+    public void testNonBlockingWriteTwiceBlockingWriteNoneNonContainerThread() throws Exception {
+        doNonBlockingTest(2, 0, false);
+    }
+
+    @Test
+    public void testNonBlockingWriteNoneBlockingWriteOnceNonContainerThread() throws Exception {
+        doNonBlockingTest(0, 1, false);
+    }
+
+    @Test
+    public void testNonBlockingWriteOnceBlockingWriteOnceNonContainerThread() throws Exception {
+        doNonBlockingTest(1, 1, false);
+    }
+
+    @Test
+    public void testNonBlockingWriteTwiceBlockingWriteOnceNonContainerThread() throws Exception {
+        doNonBlockingTest(2, 1, false);
+    }
+
+    private void doNonBlockingTest(int asyncWriteTarget, int syncWriteTarget,
+            boolean useContainerThreadToSetListener) throws Exception {
 
         Tomcat tomcat = getTomcatInstance();
 
         Context root = tomcat.addContext("", TEMP_DIR);
         Wrapper w = Tomcat.addServlet(root, "nbWrite",
-                new NonBlockingWriteServlet(asyncWriteTarget));
+                new NonBlockingWriteServlet(asyncWriteTarget, useContainerThreadToSetListener));
         w.setAsyncSupported(true);
         root.addServletMapping("/nbWrite", "nbWrite");
         Tomcat.addServlet(root, "write",
@@ -110,9 +140,12 @@ public class TestCoyoteOutputStream exte
 
         private final int asyncWriteTarget;
         private final AtomicInteger asyncWriteCount = new AtomicInteger(0);
+        private final boolean useContainerThreadToSetListener;
 
-        public NonBlockingWriteServlet(int asyncWriteTarget) {
+        public NonBlockingWriteServlet(int asyncWriteTarget,
+                boolean useContainerThreadToSetListener) {
             this.asyncWriteTarget = asyncWriteTarget;
+            this.useContainerThreadToSetListener = useContainerThreadToSetListener;
         }
 
         @Override
@@ -125,9 +158,14 @@ public class TestCoyoteOutputStream exte
 
 
             AsyncContext asyncCtxt = req.startAsync();
-            // Infinite timeout for debugging
-            asyncCtxt.setTimeout(0);
-            asyncCtxt.start(new AsyncTask(asyncCtxt, sos));
+            asyncCtxt.setTimeout(5);
+            Runnable task = new AsyncTask(asyncCtxt, sos);
+            if (useContainerThreadToSetListener) {
+                asyncCtxt.start(task);
+            } else {
+                Thread t = new Thread(task);
+                t.start();
+            }
         }
 
         private void doAsyncWrite(AsyncContext asyncCtxt,



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