You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2012/07/06 17:40:14 UTC
svn commit: r1358271 - in /tomcat/trunk/java/org/apache:
catalina/connector/CoyoteAdapter.java catalina/core/AsyncContextImpl.java
coyote/http11/Http11NioProcessor.java tomcat/util/net/SocketStatus.java
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org