Author: fhanik
Date: Fri Jul  6 15:40:14 2012
New Revision: 1358271

URL: http://svn.apache.org/viewvc?rev=1358271&view=rev
Log:
Add in the ability to catch non blocking read and write errors and propagate 
that to the servlet

Modified:
    tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
    tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SocketStatus.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1358271&r1=1358270&r2=1358271&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Fri Jul  
6 15:40:14 2012
@@ -293,6 +293,22 @@ public class CoyoteAdapter implements Ad
                 if (!asyncConImpl.timeout()) {
                     asyncConImpl.setErrorState(null);
                 }
+            } else if (status==SocketStatus.ASYNC_READ_ERROR) {
+                success = true;
+                Throwable t = 
(Throwable)req.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+                req.getAttributes().remove(RequestDispatcher.ERROR_EXCEPTION);
+                asyncConImpl.notifyReadError(t);
+                if (t != null) {
+                    asyncConImpl.setErrorState(t);
+                }
+            } else if (status==SocketStatus.ASYNC_WRITE_ERROR) {
+                success = true;
+                Throwable t = 
(Throwable)req.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+                req.getAttributes().remove(RequestDispatcher.ERROR_EXCEPTION);
+                asyncConImpl.notifyWriteError(t);
+                if (t != null) {
+                    asyncConImpl.setErrorState(t);
+                }
             }
 
 

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=1358271&r1=1358270&r2=1358271&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Fri Jul  6 
15:40:14 2012
@@ -135,6 +135,32 @@ public class AsyncContextImpl implements
         return true;
     }
 
+    public boolean notifyWriteError(Throwable error) {
+        if 
(request.getResponse().getCoyoteResponse().getWriteListener()==null) return 
false;
+        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
+        ClassLoader newCL = request.getContext().getLoader().getClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(newCL);
+            
request.getResponse().getCoyoteResponse().getWriteListener().onError(error);
+            return true;
+        } finally {
+            Thread.currentThread().setContextClassLoader(oldCL);
+        }
+    }
+
+    public boolean notifyReadError(Throwable error) {
+        if (request.getCoyoteRequest().getReadListener()==null) return false;
+        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
+        ClassLoader newCL = request.getContext().getLoader().getClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(newCL);
+            request.getCoyoteRequest().getReadListener().onError(error);
+            return true;
+        } finally {
+            Thread.currentThread().setContextClassLoader(oldCL);
+        }
+    }
+
     public boolean timeout() throws IOException {
         AtomicBoolean result = new AtomicBoolean();
         request.getCoyoteRequest().action(ActionCode.ASYNC_TIMEOUT, result);

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1358271&r1=1358270&r2=1358271&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Fri Jul  
6 15:40:14 2012
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.net.ssl.SSLEngine;
 import javax.servlet.ReadListener;
+import javax.servlet.RequestDispatcher;
 import javax.servlet.WriteListener;
 
 import org.apache.coyote.ActionCode;
@@ -192,14 +193,15 @@ public class Http11NioProcessor extends 
                     }
                 }catch (IOException x) {
                     if (log.isDebugEnabled()) log.debug("Unable to write async 
data.",x);
-                    //TODO FIXME-- fix - so we can notify of error
-                    return SocketState.CLOSED;
+                    status = SocketStatus.ASYNC_WRITE_ERROR;
+                    request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, x);
                 }
                 //return if we have more data to write
-                if (isRegisteredForWrite(attach)) {
+                if (status == SocketStatus.OPEN_WRITE && 
isRegisteredForWrite(attach)) {
                     return SocketState.LONG;
                 }
             }catch (IllegalStateException x) {
+                attach.interestOps(attach.interestOps() | 
SelectionKey.OP_WRITE);
             }
         } else if (status == SocketStatus.OPEN_READ) {
             try {
@@ -209,17 +211,18 @@ public class Http11NioProcessor extends 
                     }
                 }catch (IOException x) {
                     if (log.isDebugEnabled()) log.debug("Unable to read async 
data.",x);
-                  //TODO FIXME-- fix - so we can notify of error
-                    return SocketState.CLOSED;
+                    status = SocketStatus.ASYNC_READ_ERROR;
+                    request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, x);
                 }
                 //return if we have more data to write
             }catch (IllegalStateException x) {
+                attach.interestOps(attach.interestOps() | 
SelectionKey.OP_READ);
             }
         }
 
         SocketState state = super.asyncDispatch(status);
         //return if we have more data to write
-        if (isRegisteredForWrite(attach)) {
+        if (state == SocketState.LONG && isRegisteredForWrite(attach)) {
             return SocketState.LONG;
         } else {
             return state;
@@ -246,7 +249,7 @@ public class Http11NioProcessor extends 
     protected boolean isRegisteredForWrite(KeyAttachment attach) {
         //return if we have more data to write
         if (outputBuffer.hasDataToWrite()) {
-            attach.interestOps(SelectionKey.OP_WRITE);
+            attach.interestOps(attach.interestOps() | SelectionKey.OP_WRITE);
             return true;
         } else {
             return false;

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketStatus.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketStatus.java?rev=1358271&r1=1358270&r2=1358271&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketStatus.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketStatus.java Fri Jul  6 
15:40:14 2012
@@ -23,5 +23,5 @@ package org.apache.tomcat.util.net;
  * @author remm
  */
 public enum SocketStatus {
-    OPEN_READ, OPEN_WRITE, STOP, TIMEOUT, DISCONNECT, ERROR
+    OPEN_READ, OPEN_WRITE, STOP, TIMEOUT, DISCONNECT, ERROR, 
ASYNC_WRITE_ERROR, ASYNC_READ_ERROR
 }



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

Reply via email to