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