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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org