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 2013/10/04 13:44:03 UTC

svn commit: r1529134 - in /tomcat/trunk: java/org/apache/catalina/core/ java/org/apache/coyote/ java/org/apache/coyote/http11/ java/org/apache/tomcat/util/net/ test/org/apache/catalina/connector/

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1529134 - in /tomcat/trunk: java/org/apache/catalina/core/ java/org/apache/coyote/ java/org/apache/coyote/http11/ java/org/apache/tomcat/util/net/ test/org/apache/catalina/connector/

Posted by Mark Thomas <ma...@apache.org>.
On 04/10/2013 12:44, markt@apache.org wrote:
> 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()

This is not yet complete. There is still an intermittent NPE that I
understand the root cause of, I just need to find the time to fix it.

Mark


> 
> 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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> 


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