Author: markt
Date: Fri Oct  4 11:44:03 2013
New Revision: 1529134

URL: http://svn.apache.org/r1529134
Log:
Fix intermittent issue observed in unit test on CI system.
Container is responsible for first call on onWritePossible() / onDataAvailable()

Modified:
    tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/trunk/java/org/apache/coyote/ActionCode.java
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java

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=1529134&r1=1529133&r2=1529134&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Fri Oct  4 
11:44:03 2013
@@ -261,7 +261,7 @@ public class AsyncContextImpl implements
             logDebug("start      ");
         }
         check();
-        Runnable wrapper = new RunnableWrapper(run, context);
+        Runnable wrapper = new RunnableWrapper(run, context, 
this.request.getCoyoteRequest());
         this.request.getCoyoteRequest().action(ActionCode.ASYNC_RUN, wrapper);
     }
 
@@ -539,12 +539,15 @@ public class AsyncContextImpl implements
 
     private static class RunnableWrapper implements Runnable {
 
-        private Runnable wrapped = null;
-        private Context context = null;
+        private final Runnable wrapped;
+        private final Context context;
+        private final org.apache.coyote.Request coyoteRequest;
 
-        public RunnableWrapper(Runnable wrapped, Context ctxt) {
+        public RunnableWrapper(Runnable wrapped, Context ctxt,
+                org.apache.coyote.Request coyoteRequest) {
             this.wrapped = wrapped;
             this.context = ctxt;
+            this.coyoteRequest = coyoteRequest;
         }
 
         @Override
@@ -576,8 +579,12 @@ public class AsyncContextImpl implements
                     Thread.currentThread().setContextClassLoader(oldCL);
                 }
             }
-        }
 
+            // Since this runnable is not executing as a result of a socket
+            // event, we need to ensure that any registered dispatches are
+            // executed.
+            coyoteRequest.action(ActionCode.DISPATCH_EXECUTE, null);
+        }
     }
 
 

Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=1529134&r1=1529133&r2=1529134&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Fri Oct  4 11:44:03 2013
@@ -221,5 +221,13 @@ public enum ActionCode {
      * Indicates that the container needs to trigger a call to 
onWritePossible()
      * for the registered non-blocking write listener.
      */
-    DISPATCH_WRITE
+    DISPATCH_WRITE,
+
+    /**
+     * Execute any non-blocking dispatches that have been registered via
+     * {@link #DISPATCH_READ} or {@link #DISPATCH_WRITE}. Typically required
+     * when the non-blocking listeners are configured on a thread where the
+     * processing wasn't triggered by a read or write event on the socket.
+     */
+    DISPATCH_EXECUTE
 }

Modified: 
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1529134&r1=1529133&r2=1529134&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Fri 
Oct  4 11:44:03 2013
@@ -834,6 +834,8 @@ public abstract class AbstractHttp11Proc
             socketWrapper.addDispatch(DispatchType.NON_BLOCKING_READ);
         } else if (actionCode == ActionCode.DISPATCH_WRITE) {
             socketWrapper.addDispatch(DispatchType.NON_BLOCKING_WRITE);
+        } else if (actionCode == ActionCode.DISPATCH_EXECUTE) {
+            getEndpoint().executeNonBlockingDispatches(socketWrapper);
         } else {
             actionInternal(actionCode, param);
         }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1529134&r1=1529133&r2=1529134&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Fri Oct  
4 11:44:03 2013
@@ -635,6 +635,17 @@ public abstract class AbstractEndpoint<S
             SocketStatus socketStatus, boolean dispatch);
 
 
+    public void executeNonBlockingDispatches(SocketWrapper<S> socketWrapper) {
+        // Synchronise on the socket wrapper to ensure no other threads are
+        // working with the socket
+        synchronized (socketWrapper) {
+            while (socketWrapper.hasNextDispatch()) {
+                DispatchType dispatchType = socketWrapper.getNextDispatch();
+                processSocket(socketWrapper, dispatchType.getSocketStatus(), 
false);
+            }
+        }
+    }
+
     // ------------------------------------------------------- Lifecycle 
methods
 
     /*

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=1529134&r1=1529133&r2=1529134&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestCoyoteOutputStream.java 
Fri Oct  4 11:44:03 2013
@@ -159,11 +159,6 @@ public class TestCoyoteOutputStream exte
             @Override
             public void run() {
                 sos.setWriteListener(new MyWriteListener(asyncCtxt, sos));
-                try {
-                    doAsyncWrite(asyncCtxt, sos);
-                } catch (IOException ioe) {
-                    throw new RuntimeException(ioe);
-                }
             }
         }
 



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

Reply via email to