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 2019/07/10 15:33:25 UTC

[tomcat] 01/02: Push the error state tracking down to the Coyote Response

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit b9ccc2d576c6e6cd60cd1841ba7ff3382f3f24ef
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Feb 1 10:52:53 2019 +0000

    Push the error state tracking down to the Coyote Response
    
    This is to support error handling of async requests dispatched to a
    container provided thread.
---
 java/org/apache/catalina/connector/Response.java | 41 ++-------------
 java/org/apache/coyote/Response.java             | 67 +++++++++++++++++++++++-
 2 files changed, 69 insertions(+), 39 deletions(-)

diff --git a/java/org/apache/catalina/connector/Response.java b/java/org/apache/catalina/connector/Response.java
index 19399d6..539fe6b 100644
--- a/java/org/apache/catalina/connector/Response.java
+++ b/java/org/apache/catalina/connector/Response.java
@@ -33,7 +33,6 @@ import java.util.List;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.Vector;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.SessionTrackingMode;
@@ -219,37 +218,6 @@ public class Response implements HttpServletResponse {
      */
     private boolean isCharacterEncodingSet = false;
 
-    /**
-     * With the introduction of async processing and the possibility of
-     * non-container threads calling sendError() tracking the current error
-     * state and ensuring that the correct error page is called becomes more
-     * complicated. This state attribute helps by tracking the current error
-     * state and informing callers that attempt to change state if the change
-     * was successful or if another thread got there first.
-     *
-     * <pre>
-     * The state machine is very simple:
-     *
-     * 0 - NONE
-     * 1 - NOT_REPORTED
-     * 2 - REPORTED
-     *
-     *
-     *   -->---->-- >NONE
-     *   |   |        |
-     *   |   |        | setError()
-     *   ^   ^        |
-     *   |   |       \|/
-     *   |   |-<-NOT_REPORTED
-     *   |            |
-     *   ^            | report()
-     *   |            |
-     *   |           \|/
-     *   |----<----REPORTED
-     * </pre>
-     */
-    private final AtomicInteger errorState = new AtomicInteger(0);
-
 
     /**
      * Using output stream flag.
@@ -289,7 +257,6 @@ public class Response implements HttpServletResponse {
         usingWriter = false;
         appCommitted = false;
         included = false;
-        errorState.set(0);
         isCharacterEncodingSet = false;
 
         if (Globals.IS_SECURITY_ENABLED || Connector.RECYCLE_FACADES) {
@@ -480,7 +447,7 @@ public class Response implements HttpServletResponse {
      * Set the error flag.
      */
     public boolean setError() {
-        boolean result = errorState.compareAndSet(0, 1);
+        boolean result = getCoyoteResponse().setError();
         if (result) {
             Wrapper wrapper = getRequest().getWrapper();
             if (wrapper != null) {
@@ -495,17 +462,17 @@ public class Response implements HttpServletResponse {
      * Error flag accessor.
      */
     public boolean isError() {
-        return errorState.get() > 0;
+        return getCoyoteResponse().isError();
     }
 
 
     public boolean isErrorReportRequired() {
-        return errorState.get() == 1;
+        return getCoyoteResponse().isErrorReportRequired();
     }
 
 
     public boolean setErrorReported() {
-        return errorState.compareAndSet(1, 2);
+        return getCoyoteResponse().setErrorReported();
     }
 
 
diff --git a/java/org/apache/coyote/Response.java b/java/org/apache/coyote/Response.java
index 38e62b2..568eb19 100644
--- a/java/org/apache/coyote/Response.java
+++ b/java/org/apache/coyote/Response.java
@@ -19,6 +19,7 @@ package org.apache.coyote;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Locale;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.http.MimeHeaders;
@@ -103,14 +104,45 @@ public final class Response {
     private long commitTime = -1;
 
     /**
+     * Has the charset been explicitly set.
+     */
+    boolean charsetSet = false;
+
+    /**
      * Holds request error exception.
      */
     Exception errorException = null;
 
     /**
-     * Has the charset been explicitly set.
+     * With the introduction of async processing and the possibility of
+     * non-container threads calling sendError() tracking the current error
+     * state and ensuring that the correct error page is called becomes more
+     * complicated. This state attribute helps by tracking the current error
+     * state and informing callers that attempt to change state if the change
+     * was successful or if another thread got there first.
+     *
+     * <pre>
+     * The state machine is very simple:
+     *
+     * 0 - NONE
+     * 1 - NOT_REPORTED
+     * 2 - REPORTED
+     *
+     *
+     *   -->---->-- >NONE
+     *   |   |        |
+     *   |   |        | setError()
+     *   ^   ^        |
+     *   |   |       \|/
+     *   |   |-<-NOT_REPORTED
+     *   |            |
+     *   ^            | report()
+     *   |            |
+     *   |           \|/
+     *   |----<----REPORTED
+     * </pre>
      */
-    boolean charsetSet = false;
+    private final AtomicInteger errorState = new AtomicInteger(0);
 
     Request req;
 
@@ -260,6 +292,36 @@ public final class Response {
     }
 
 
+    /**
+     * Set the error flag.
+     *
+     * @return <code>false</code> if the error flag was already set
+     */
+    public boolean setError() {
+        return errorState.compareAndSet(0, 1);
+    }
+
+
+    /**
+     * Error flag accessor.
+     *
+     * @return <code>true</code> if the response has encountered an error
+     */
+    public boolean isError() {
+        return errorState.get() > 0;
+    }
+
+
+    public boolean isErrorReportRequired() {
+        return errorState.get() == 1;
+    }
+
+
+    public boolean setErrorReported() {
+        return errorState.compareAndSet(1, 2);
+    }
+
+
     // -------------------- Methods --------------------
 
     public void reset() throws IllegalStateException {
@@ -533,6 +595,7 @@ public final class Response {
         committed = false;
         commitTime = -1;
         errorException = null;
+        errorState.set(0);
         headers.clear();
 
         // update counters


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