view src/org/eclipse/jetty/server/AsyncContinuation.java @ 936:237ace6e8bc2

simplify AsyncContinuation
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 09 Oct 2016 21:35:26 -0600
parents aa7dc1802d29
children 0541b6034003
line wrap: on
line source

//
//  ========================================================================
//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server;

import org.eclipse.jetty.continuation.Continuation;
import org.eclipse.jetty.io.EndPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/* ------------------------------------------------------------ */
/** Implementation of Continuation interfaces
 * 
 */
public final class AsyncContinuation implements Continuation
{
	private static final Logger LOG = LoggerFactory.getLogger(AsyncContinuation.class);

	private final static long DEFAULT_TIMEOUT=30000L;
		
	// STATES:
	//               handling()    suspend()     unhandle()    resume()       complete()  doComplete()
	//                             startAsync()                dispatch()   
	// IDLE          DISPATCHED      
	// DISPATCHED                  ASYNCSTARTED  UNCOMPLETED
	// ASYNCSTARTED                              ASYNCWAIT     REDISPATCHING  COMPLETING
	// REDISPATCHING                             REDISPATCHED  
	// ASYNCWAIT                                               REDISPATCH     COMPLETING
	// REDISPATCH    REDISPATCHED
	// REDISPATCHED                ASYNCSTARTED  UNCOMPLETED
	// COMPLETING    UNCOMPLETED                 UNCOMPLETED
	// UNCOMPLETED                                                                        COMPLETED
	// COMPLETED
	private static final int __IDLE=0;         // Idle request
	private static final int __DISPATCHED=1;   // Request dispatched to filter/servlet
	private static final int __UNCOMPLETED=8;  // Request is completable
	private static final int __COMPLETED=9;    // Request is complete
	
	/* ------------------------------------------------------------ */
	protected AbstractHttpConnection _connection;

	/* ------------------------------------------------------------ */
	private int _state;
	
	AsyncContinuation()
	{
		_state=__IDLE;
	}

	protected synchronized void setConnection(final AbstractHttpConnection connection)
	{
		_connection=connection;
	}

	
	@Override
	public synchronized String toString()
	{
		return super.toString()+"@"+getStatusString();
	}

	private synchronized String getStatusString()
	{
		return
		((_state==__IDLE)?"IDLE":
			(_state==__DISPATCHED)?"DISPATCHED":
										(_state==__UNCOMPLETED)?"UNCOMPLETED":
											(_state==__COMPLETED)?"COMPLETE":
												("UNKNOWN?"+_state));
	}

	protected synchronized void handling()
	{
		switch(_state)
		{
			case __IDLE:
				_state=__DISPATCHED;
				return;
				
			default:
				throw new IllegalStateException(this.getStatusString());
		}
	}

	/* ------------------------------------------------------------ */
	/**
	 * Signal that the HttpConnection has finished handling the request.
	 * For blocking connectors, this call may block if the request has
	 * been suspended (startAsync called).
	 * @return true if handling is complete, false if the request should 
	 * be handled again (eg because of a resume that happened before unhandle was called)
	 */
	protected synchronized void unhandle()
	{
		switch(_state)
		{
			case __DISPATCHED:
				_state = __UNCOMPLETED;
				return;

			default:
				throw new IllegalStateException(this.getStatusString());
		}
	}

		
	protected synchronized void doComplete(Throwable ex)
	{
		switch(_state)
		{
			case __UNCOMPLETED:
				_state = __COMPLETED;
				break;
				
			default:
				throw new IllegalStateException(this.getStatusString());
		}
	}

	protected synchronized void recycle()
	{
		switch(_state)
		{
			case __DISPATCHED:
				throw new IllegalStateException(getStatusString());
			default:
				_state=__IDLE;
		}
		cancelTimeout();
	}    
	
	private void cancelTimeout()
	{
		EndPoint endp=_connection.getEndPoint();
		if (endp.isBlocking())
		{
			synchronized(this)
			{
				this.notifyAll();
			}
		}
	}

	synchronized boolean isUncompleted()
	{
		return _state==__UNCOMPLETED;
	} 
}