Author: markt
Date: Mon Sep 21 21:36:45 2015
New Revision: 1704428
URL: http://svn.apache.org/viewvc?rev=1704428&view=rev
Log:
Add some basic Servlet 3.0 async support to HTTP/2.
The async examples (excluding the stock ticker) work with this commit.
I'm looking into why the stock ticker example doesn't work.
Async timeouts are also TODO.
Modified:
tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java
Modified: tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java?rev=1704428&r1=1704427&r2=1704428&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java Mon Sep 21
21:36:45 2015
@@ -25,6 +25,9 @@ import javax.servlet.http.HttpUpgradeHan
import org.apache.coyote.AbstractProcessor;
import org.apache.coyote.ActionCode;
import org.apache.coyote.Adapter;
+import org.apache.coyote.AsyncContextCallback;
+import org.apache.coyote.AsyncStateMachine;
+import org.apache.coyote.ContainerThreadMarker;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
@@ -39,6 +42,7 @@ public class StreamProcessor extends Abs
private static final StringManager sm =
StringManager.getManager(StreamProcessor.class);
private final Stream stream;
+ private final AsyncStateMachine asyncStateMachine;
private volatile SSLSupport sslSupport;
@@ -46,6 +50,7 @@ public class StreamProcessor extends Abs
public StreamProcessor(Stream stream, Adapter adapter,
SocketWrapperBase<?> socketWrapper) {
super(stream.getCoyoteRequest(), stream.getCoyoteResponse());
this.stream = stream;
+ asyncStateMachine = new AsyncStateMachine(this);
setAdapter(adapter);
setSocketWrapper(socketWrapper);
}
@@ -53,13 +58,28 @@ public class StreamProcessor extends Abs
@Override
public void run() {
+ // HTTP/2 equivalent of AbstractConnectionHandler#process()
+ ContainerThreadMarker.set();
+ SocketState state = SocketState.CLOSED;
try {
- adapter.service(request, response);
- // Ensure the response is complete
- response.action(ActionCode.CLOSE, null);
+ do {
+ if (asyncStateMachine.isAsync()) {
+ adapter.asyncDispatch(request, response,
SocketStatus.OPEN_READ);
+ } else {
+ adapter.service(request, response);
+ }
+
+ if (asyncStateMachine.isAsync()) {
+ state = asyncStateMachine.asyncPostProcess();
+ } else {
+ response.action(ActionCode.CLOSE, null);
+ }
+ } while (state == SocketState.ASYNC_END);
} catch (Exception e) {
// TODO
e.printStackTrace();
+ } finally {
+ ContainerThreadMarker.clear();
}
}
@@ -95,6 +115,69 @@ public class StreamProcessor extends Abs
break;
}
+ // Servlet 3.0 asynchronous support
+ case ASYNC_START: {
+ asyncStateMachine.asyncStart((AsyncContextCallback) param);
+ break;
+ }
+ case ASYNC_COMPLETE: {
+ if (asyncStateMachine.asyncComplete()) {
+ socketWrapper.getEndpoint().getExecutor().execute(this);
+ }
+ break;
+ }
+ case ASYNC_DISPATCH: {
+ if (asyncStateMachine.asyncDispatch()) {
+ socketWrapper.getEndpoint().getExecutor().execute(this);
+ }
+ break;
+ }
+ case ASYNC_DISPATCHED: {
+ asyncStateMachine.asyncDispatched();
+ break;
+ }
+ case ASYNC_ERROR: {
+ asyncStateMachine.asyncError();
+ break;
+ }
+ case ASYNC_IS_ASYNC: {
+ ((AtomicBoolean) param).set(asyncStateMachine.isAsync());
+ break;
+ }
+ case ASYNC_IS_COMPLETING: {
+ ((AtomicBoolean) param).set(asyncStateMachine.isCompleting());
+ break;
+ }
+ case ASYNC_IS_DISPATCHING: {
+ ((AtomicBoolean)
param).set(asyncStateMachine.isAsyncDispatching());
+ break;
+ }
+ case ASYNC_IS_ERROR: {
+ ((AtomicBoolean) param).set(asyncStateMachine.isAsyncError());
+ break;
+ }
+ case ASYNC_IS_STARTED: {
+ ((AtomicBoolean) param).set(asyncStateMachine.isAsyncStarted());
+ break;
+ }
+ case ASYNC_IS_TIMINGOUT: {
+ ((AtomicBoolean) param).set(asyncStateMachine.isAsyncTimingOut());
+ break;
+ }
+ case ASYNC_RUN: {
+ asyncStateMachine.asyncRun((Runnable) param);
+ break;
+ }
+ case ASYNC_SETTIMEOUT: {
+ // TODO
+ break;
+ }
+ case ASYNC_TIMEOUT: {
+ AtomicBoolean result = (AtomicBoolean) param;
+ result.set(asyncStateMachine.asyncTimeout());
+ break;
+ }
+
//case REQ_HOST_ATTRIBUTE: {
// request.remoteHost().setString(socketWrapper.getRemoteHost());
// break;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]