Add some modifications to the state machine. Timeout and error are an async dispatch...
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 16 Oct 2009 00:06:14 +0000 (00:06 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 16 Oct 2009 00:06:14 +0000 (00:06 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@825708 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/connector/CoyoteAdapter.java
java/org/apache/catalina/core/AsyncContextImpl.java
webapps/examples/WEB-INF/classes/async/AsyncStockServlet.java

index 7ac3b21..1ae3408 100644 (file)
@@ -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
index fa985ac..e7dcfe9 100644 (file)
@@ -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) {
index 535d606..560d234 100644 (file)
@@ -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);
         }
     }