From 6d068bcb6f36c35ccf9f9bd996d54d4336e6d308 Mon Sep 17 00:00:00 2001 From: fhanik Date: Fri, 16 Oct 2009 00:06:14 +0000 Subject: [PATCH] Add some modifications to the state machine. Timeout and error are an async dispatch, and its unclear what the state should be. Since both those actions should stop the event, we set the state to COMPLETING git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@825708 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/connector/CoyoteAdapter.java | 2 +- java/org/apache/catalina/core/AsyncContextImpl.java | 16 ++++++++++++---- .../WEB-INF/classes/async/AsyncStockServlet.java | 3 +-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/java/org/apache/catalina/connector/CoyoteAdapter.java b/java/org/apache/catalina/connector/CoyoteAdapter.java index 7ac3b21d3..1ae3408d3 100644 --- a/java/org/apache/catalina/connector/CoyoteAdapter.java +++ b/java/org/apache/catalina/connector/CoyoteAdapter.java @@ -272,7 +272,7 @@ public class CoyoteAdapter //configure settings for timed out asyncConImpl.setTimeoutState(); } - if (status==SocketStatus.ERROR) { + if (status==SocketStatus.ERROR || status==SocketStatus.STOP || status==SocketStatus.DISCONNECT) { AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); //TODO SERVLET3 - async //configure settings for timed out diff --git a/java/org/apache/catalina/core/AsyncContextImpl.java b/java/org/apache/catalina/core/AsyncContextImpl.java index fa985ac8b..e7dcfe9bf 100644 --- a/java/org/apache/catalina/core/AsyncContextImpl.java +++ b/java/org/apache/catalina/core/AsyncContextImpl.java @@ -72,7 +72,9 @@ public class AsyncContextImpl implements AsyncContext { @Override public void complete() { - if (state.compareAndSet(AsyncState.STARTED, AsyncState.COMPLETING) || + if (state.get()==AsyncState.COMPLETING) { + //do nothing + } else if (state.compareAndSet(AsyncState.STARTED, AsyncState.COMPLETING) || state.compareAndSet(AsyncState.DISPATCHED, AsyncState.COMPLETING)) { // TODO SERVLET3 - async AtomicBoolean dispatched = new AtomicBoolean(false); @@ -254,7 +256,7 @@ public class AsyncContextImpl implements AsyncContext { } public void doInternalDispatch() throws ServletException, IOException { - if (this.state.compareAndSet(AsyncState.TIMING_OUT, AsyncState.DISPATCHED)) { + if (this.state.compareAndSet(AsyncState.TIMING_OUT, AsyncState.COMPLETING)) { log.debug("TIMING OUT!"); boolean listenerInvoked = false; for (AsyncListenerWrapper listener : listeners) { @@ -265,11 +267,17 @@ public class AsyncContextImpl implements AsyncContext { ((HttpServletResponse)servletResponse).setStatus(500); } doInternalComplete(true); - } else if (this.state.compareAndSet(AsyncState.ERROR_DISPATCHING, AsyncState.DISPATCHED)) { + } else if (this.state.compareAndSet(AsyncState.ERROR_DISPATCHING, AsyncState.COMPLETING)) { log.debug("ON ERROR!"); boolean listenerInvoked = false; for (AsyncListenerWrapper listener : listeners) { - listener.fireOnError(event); + try { + listener.fireOnError(event); + }catch (IllegalStateException x) { + log.debug("Listener invoked invalid state.",x); + }catch (Exception x) { + log.debug("Exception during onError.",x); + } listenerInvoked = true; } if (!listenerInvoked) { diff --git a/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java b/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java index 535d606ed..560d234ba 100644 --- a/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java +++ b/webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java @@ -117,8 +117,7 @@ public class AsyncStockServlet extends HttpServlet implements TickListener, Asyn @Override public void onComplete(AsyncEvent event) throws IOException { - clients.remove(event.getRequest().getAsyncContext()); - if (clientcount.decrementAndGet()==0) { + if (clients.remove(event.getRequest().getAsyncContext()) && clientcount.decrementAndGet()==0) { ticker.removeTickListener(this); } } -- 2.11.0