changeset 917:1fc8ee20cb18

remove doSuspend
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 09 Oct 2016 03:23:55 -0600
parents 4de7f6e9c453
children 7b62446899c6
files src/org/eclipse/jetty/continuation/Continuation.java src/org/eclipse/jetty/server/AsyncContinuation.java src/org/eclipse/jetty/server/Request.java
diffstat 3 files changed, 264 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
diff -r 4de7f6e9c453 -r 1fc8ee20cb18 src/org/eclipse/jetty/continuation/Continuation.java
--- a/src/org/eclipse/jetty/continuation/Continuation.java	Sun Oct 09 02:08:40 2016 -0600
+++ b/src/org/eclipse/jetty/continuation/Continuation.java	Sun Oct 09 03:23:55 2016 -0600
@@ -144,277 +144,277 @@
  */
 public interface Continuation
 {
-    public final static String ATTRIBUTE = "org.eclipse.jetty.continuation";
+	public final static String ATTRIBUTE = "org.eclipse.jetty.continuation";
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Set the continuation timeout.
-     * 
-     * @param timeoutMs
-     *            The time in milliseconds to wait before expiring this
-     *            continuation after a call to {@link #suspend()} or {@link #suspend(ServletResponse)}.
-     *            A timeout of <=0 means the continuation will never expire.
-     */
-    void setTimeout(long timeoutMs);
+	/* ------------------------------------------------------------ */
+	/**
+	 * Set the continuation timeout.
+	 * 
+	 * @param timeoutMs
+	 *            The time in milliseconds to wait before expiring this
+	 *            continuation after a call to {@link #suspend()} or {@link #suspend(ServletResponse)}.
+	 *            A timeout of <=0 means the continuation will never expire.
+	 */
+	void setTimeout(long timeoutMs);
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Suspend the processing of the request and associated
-     * {@link ServletResponse}.
-     * 
-     * <p>
-     * After this method has been called, the lifecycle of the request will be
-     * extended beyond the return to the container from the
-     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
-     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
-     * calls. When a suspended request is returned to the container after
-     * a dispatch, then the container will not commit the associated response
-     * (unless an exception other than {@link ContinuationThrowable} is thrown).
-     * </p>
-     * 
-     * <p>
-     * When the thread calling the filter chain and/or servlet has returned to
-     * the container with a suspended request, the thread is freed for other
-     * tasks and the request is held until either:
-     * <ul>
-     * <li>a call to {@link #resume()}.</li>
-     * <li>a call to {@link #complete()}.</li>
-     * <li>the timeout expires.</li>
-     * </ul>
-     * <p>
-     * Typically suspend with no arguments is uses when a call to {@link #resume()}
-     * is expected. If a call to {@link #complete()} is expected, then the 
-     * {@link #suspend(ServletResponse)} method should be used instead of this method.
-     * </p>
-     * 
-     * @exception IllegalStateException
-     *                If the request cannot be suspended
-     */
-    void suspend();
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Suspend the processing of the request and associated
-     * {@link ServletResponse}.
-     * 
-     * <p>
-     * After this method has been called, the lifecycle of the request will be
-     * extended beyond the return to the container from the
-     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
-     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
-     * calls. When a suspended request is returned to the container after
-     * a dispatch, then the container will not commit the associated response
-     * (unless an exception other than {@link ContinuationThrowable} is thrown).
-     * </p>
-     * <p>
-     * When the thread calling the filter chain and/or servlet has returned to
-     * the container with a suspended request, the thread is freed for other
-     * tasks and the request is held until either:
-     * <ul>
-     * <li>a call to {@link #resume()}.</li>
-     * <li>a call to {@link #complete()}.</li>
-     * <li>the timeout expires.</li>
-     * </ul>
-     * <p>
-     * Typically suspend with a response argument is uses when a call to {@link #complete()}
-     * is expected. If a call to {@link #resume()} is expected, then the 
-     * {@link #suspend()} method should be used instead of this method.
-     * </p>
-     * <p>
-     * Filters that may wrap the response object should check {@link #isResponseWrapped()}
-     * to decide if they should destroy/finish the wrapper. If {@link #isResponseWrapped()}
-     * returns true, then the wrapped request has been passed to the asynchronous
-     * handler and the wrapper should not be destroyed/finished until after a call to 
-     * {@link #complete()} (potentially using a {@link ContinuationListener#onComplete(Continuation)}
-     * listener).
-     * 
-     * @param response The response to return via a call to {@link #getServletResponse()}
-     * @exception IllegalStateException
-     *                If the request cannot be suspended
-     */
-    void suspend(ServletResponse response);
+	/* ------------------------------------------------------------ */
+	/**
+	 * Suspend the processing of the request and associated
+	 * {@link ServletResponse}.
+	 * 
+	 * <p>
+	 * After this method has been called, the lifecycle of the request will be
+	 * extended beyond the return to the container from the
+	 * {@link Servlet#service(ServletRequest, ServletResponse)} method and
+	 * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
+	 * calls. When a suspended request is returned to the container after
+	 * a dispatch, then the container will not commit the associated response
+	 * (unless an exception other than {@link ContinuationThrowable} is thrown).
+	 * </p>
+	 * 
+	 * <p>
+	 * When the thread calling the filter chain and/or servlet has returned to
+	 * the container with a suspended request, the thread is freed for other
+	 * tasks and the request is held until either:
+	 * <ul>
+	 * <li>a call to {@link #resume()}.</li>
+	 * <li>a call to {@link #complete()}.</li>
+	 * <li>the timeout expires.</li>
+	 * </ul>
+	 * <p>
+	 * Typically suspend with no arguments is uses when a call to {@link #resume()}
+	 * is expected. If a call to {@link #complete()} is expected, then the 
+	 * {@link #suspend(ServletResponse)} method should be used instead of this method.
+	 * </p>
+	 * 
+	 * @exception IllegalStateException
+	 *                If the request cannot be suspended
+	 */
+//	void suspend();
+	
+	
+	/* ------------------------------------------------------------ */
+	/**
+	 * Suspend the processing of the request and associated
+	 * {@link ServletResponse}.
+	 * 
+	 * <p>
+	 * After this method has been called, the lifecycle of the request will be
+	 * extended beyond the return to the container from the
+	 * {@link Servlet#service(ServletRequest, ServletResponse)} method and
+	 * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
+	 * calls. When a suspended request is returned to the container after
+	 * a dispatch, then the container will not commit the associated response
+	 * (unless an exception other than {@link ContinuationThrowable} is thrown).
+	 * </p>
+	 * <p>
+	 * When the thread calling the filter chain and/or servlet has returned to
+	 * the container with a suspended request, the thread is freed for other
+	 * tasks and the request is held until either:
+	 * <ul>
+	 * <li>a call to {@link #resume()}.</li>
+	 * <li>a call to {@link #complete()}.</li>
+	 * <li>the timeout expires.</li>
+	 * </ul>
+	 * <p>
+	 * Typically suspend with a response argument is uses when a call to {@link #complete()}
+	 * is expected. If a call to {@link #resume()} is expected, then the 
+	 * {@link #suspend()} method should be used instead of this method.
+	 * </p>
+	 * <p>
+	 * Filters that may wrap the response object should check {@link #isResponseWrapped()}
+	 * to decide if they should destroy/finish the wrapper. If {@link #isResponseWrapped()}
+	 * returns true, then the wrapped request has been passed to the asynchronous
+	 * handler and the wrapper should not be destroyed/finished until after a call to 
+	 * {@link #complete()} (potentially using a {@link ContinuationListener#onComplete(Continuation)}
+	 * listener).
+	 * 
+	 * @param response The response to return via a call to {@link #getServletResponse()}
+	 * @exception IllegalStateException
+	 *                If the request cannot be suspended
+	 */
+//	void suspend(ServletResponse response);
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Resume a suspended request.
-     * 
-     * <p>
-     * This method can be called by any thread that has been passed a reference
-     * to a continuation. When called the request is redispatched to the
-     * normal filter chain and servlet processing with {@link #isInitial()} false.
-     * </p>
-     * <p>
-     * If resume is called before a suspended request is returned to the
-     * container (ie the thread that called {@link #suspend()} is still
-     * within the filter chain and/or servlet service method), then the resume
-     * does not take effect until the call to the filter chain and/or servlet
-     * returns to the container. In this case both {@link #isSuspended()} and
-     * {@link #isResumed()} return true. Multiple calls to resume are ignored.
-     * </p>
-     * <p>
-     * Typically resume() is used after a call to {@link #suspend()} with
-     * no arguments. The dispatch after a resume call will use the original
-     * request and response objects, even if {@link #suspend(ServletResponse)} 
-     * had been passed a wrapped response.
-     * </p>
-     * 
-     * @see #suspend()
-     * @exception IllegalStateException if the request is not suspended.
-     * 
-     */
-    void resume();
+	/* ------------------------------------------------------------ */
+	/**
+	 * Resume a suspended request.
+	 * 
+	 * <p>
+	 * This method can be called by any thread that has been passed a reference
+	 * to a continuation. When called the request is redispatched to the
+	 * normal filter chain and servlet processing with {@link #isInitial()} false.
+	 * </p>
+	 * <p>
+	 * If resume is called before a suspended request is returned to the
+	 * container (ie the thread that called {@link #suspend()} is still
+	 * within the filter chain and/or servlet service method), then the resume
+	 * does not take effect until the call to the filter chain and/or servlet
+	 * returns to the container. In this case both {@link #isSuspended()} and
+	 * {@link #isResumed()} return true. Multiple calls to resume are ignored.
+	 * </p>
+	 * <p>
+	 * Typically resume() is used after a call to {@link #suspend()} with
+	 * no arguments. The dispatch after a resume call will use the original
+	 * request and response objects, even if {@link #suspend(ServletResponse)} 
+	 * had been passed a wrapped response.
+	 * </p>
+	 * 
+	 * @see #suspend()
+	 * @exception IllegalStateException if the request is not suspended.
+	 * 
+	 */
+	void resume();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Complete a suspended request.
-     * 
-     * <p>
-     * This method can be called by any thread that has been passed a reference
-     * to a suspended request. When a request is completed, the associated
-     * response object committed and flushed. The request is not redispatched.
-     * </p>
-     * 
-     * <p>
-     * If complete is called before a suspended request is returned to the
-     * container (ie the thread that called {@link #suspend()} is still
-     * within the filter chain and/or servlet service method), then the complete
-     * does not take effect until the call to the filter chain and/or servlet
-     * returns to the container. In this case both {@link #isSuspended()} and
-     * {@link #isResumed()} return true.
-     * </p>
-     * 
-     * <p>
-     * Typically resume() is used after a call to {@link #suspend(ServletResponse)} with
-     * a possibly wrapped response. The async handler should use the response
-     * provided by {@link #getServletResponse()} to write the response before
-     * calling {@link #complete()}. If the request was suspended with a 
-     * call to {@link #suspend()} then no response object will be available via
-     * {@link #getServletResponse()}.
-     * </p>
-     * 
-     * <p>
-     * Once complete has been called and any thread calling the filter chain
-     * and/or servlet chain has returned to the container, the request lifecycle
-     * is complete. The container is able to recycle request objects, so it is
-     * not valid hold a request or continuation reference after the end of the 
-     * life cycle.
-     * 
-     * @see #suspend()
-     * @exception IllegalStateException
-     *                if the request is not suspended.
-     * 
-     */
-    void complete();
+	/* ------------------------------------------------------------ */
+	/**
+	 * Complete a suspended request.
+	 * 
+	 * <p>
+	 * This method can be called by any thread that has been passed a reference
+	 * to a suspended request. When a request is completed, the associated
+	 * response object committed and flushed. The request is not redispatched.
+	 * </p>
+	 * 
+	 * <p>
+	 * If complete is called before a suspended request is returned to the
+	 * container (ie the thread that called {@link #suspend()} is still
+	 * within the filter chain and/or servlet service method), then the complete
+	 * does not take effect until the call to the filter chain and/or servlet
+	 * returns to the container. In this case both {@link #isSuspended()} and
+	 * {@link #isResumed()} return true.
+	 * </p>
+	 * 
+	 * <p>
+	 * Typically resume() is used after a call to {@link #suspend(ServletResponse)} with
+	 * a possibly wrapped response. The async handler should use the response
+	 * provided by {@link #getServletResponse()} to write the response before
+	 * calling {@link #complete()}. If the request was suspended with a 
+	 * call to {@link #suspend()} then no response object will be available via
+	 * {@link #getServletResponse()}.
+	 * </p>
+	 * 
+	 * <p>
+	 * Once complete has been called and any thread calling the filter chain
+	 * and/or servlet chain has returned to the container, the request lifecycle
+	 * is complete. The container is able to recycle request objects, so it is
+	 * not valid hold a request or continuation reference after the end of the 
+	 * life cycle.
+	 * 
+	 * @see #suspend()
+	 * @exception IllegalStateException
+	 *                if the request is not suspended.
+	 * 
+	 */
+	void complete();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true after {@link #suspend()} has been called and before the
-     *         request has been redispatched due to being resumed, completed or
-     *         timed out.
-     */
-    boolean isSuspended();
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return true after {@link #suspend()} has been called and before the
+	 *         request has been redispatched due to being resumed, completed or
+	 *         timed out.
+	 */
+	boolean isSuspended();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true if the request has been redispatched by a call to
-     *         {@link #resume()}. Returns false after any subsequent call to
-     *         suspend
-     */
-    boolean isResumed();
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return true if the request has been redispatched by a call to
+	 *         {@link #resume()}. Returns false after any subsequent call to
+	 *         suspend
+	 */
+	boolean isResumed();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true after a request has been redispatched as the result of a
-     *         timeout. Returns false after any subsequent call to suspend.
-     */
-    boolean isExpired();
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return true after a request has been redispatched as the result of a
+	 *         timeout. Returns false after any subsequent call to suspend.
+	 */
+	boolean isExpired();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true while the request is within the initial dispatch to the
-     *         filter chain and/or servlet. Will return false once the calling
-     *         thread has returned to the container after suspend has been
-     *         called and during any subsequent redispatch.
-     */
-    boolean isInitial();
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return true while the request is within the initial dispatch to the
+	 *         filter chain and/or servlet. Will return false once the calling
+	 *         thread has returned to the container after suspend has been
+	 *         called and during any subsequent redispatch.
+	 */
+	boolean isInitial();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Is the suspended response wrapped.
-     * <p>
-     * Filters that wrap the response object should check this method to 
-     * determine if they should destroy/finish the wrapped response. If 
-     * the request was suspended with a call to {@link #suspend(ServletResponse)}
-     * that passed the wrapped response, then the filter should register
-     * a {@link ContinuationListener} to destroy/finish the wrapped response
-     * during a call to {@link ContinuationListener#onComplete(Continuation)}.
-     * @return True if {@link #suspend(ServletResponse)} has been passed a
-     * {@link ServletResponseWrapper} instance.
-     */
-    boolean isResponseWrapped();
+	/* ------------------------------------------------------------ */
+	/**
+	 * Is the suspended response wrapped.
+	 * <p>
+	 * Filters that wrap the response object should check this method to 
+	 * determine if they should destroy/finish the wrapped response. If 
+	 * the request was suspended with a call to {@link #suspend(ServletResponse)}
+	 * that passed the wrapped response, then the filter should register
+	 * a {@link ContinuationListener} to destroy/finish the wrapped response
+	 * during a call to {@link ContinuationListener#onComplete(Continuation)}.
+	 * @return True if {@link #suspend(ServletResponse)} has been passed a
+	 * {@link ServletResponseWrapper} instance.
+	 */
+	boolean isResponseWrapped();
 
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get the suspended response.
-     * @return the {@link ServletResponse} passed to {@link #suspend(ServletResponse)}.
-     */
-    ServletResponse getServletResponse();
-    
-    /* ------------------------------------------------------------ */
-    /** 
-     * Add a ContinuationListener.
-     * 
-     * @param listener
-     */
-    void addContinuationListener(ContinuationListener listener);
-    
-    /* ------------------------------------------------------------ */
-    /** Set a request attribute.
-     * This method is a convenience method to call the {@link ServletRequest#setAttribute(String, Object)}
-     * method on the associated request object.
-     * This is a thread safe call and may be called by any thread.
-     * @param name the attribute name
-     * @param attribute the attribute value
-     */
-    public void setAttribute(String name, Object attribute);
-    
-    /* ------------------------------------------------------------ */
-    /** Get a request attribute.
-     * This method is a convenience method to call the {@link ServletRequest#getAttribute(String)}
-     * method on the associated request object.
-     * This is a thread safe call and may be called by any thread.
-     * @param name the attribute name
-     * @return the attribute value
-     */
-    public Object getAttribute(String name);
-    
-    /* ------------------------------------------------------------ */
-    /** Remove a request attribute.
-     * This method is a convenience method to call the {@link ServletRequest#removeAttribute(String)}
-     * method on the associated request object.
-     * This is a thread safe call and may be called by any thread.
-     * @param name the attribute name
-     */
-    public void removeAttribute(String name);
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Undispatch the request.
-     * <p>
-     * This method can be called on a suspended continuation in order
-     * to exit the dispatch to the filter/servlet by throwing a {@link ContinuationThrowable}
-     * which is caught either by the container or the {@link ContinuationFilter}.
-     * This is an alternative to simply returning from the dispatch in the case
-     * where filters in the filter chain may not be prepared to handle a suspended
-     * request.
-     * </p>
-     * This method should only be used as a last resort and a normal return is a prefereable
-     * solution if filters can be updated to handle that case.
-     * 
-     * @throws ContinuationThrowable thrown if the request is suspended. The instance of the 
-     * exception may be reused on subsequent calls, so the stack frame may not be accurate.
-     */
-    public void undispatch() throws ContinuationThrowable;
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get the suspended response.
+	 * @return the {@link ServletResponse} passed to {@link #suspend(ServletResponse)}.
+	 */
+	ServletResponse getServletResponse();
+	
+	/* ------------------------------------------------------------ */
+	/** 
+	 * Add a ContinuationListener.
+	 * 
+	 * @param listener
+	 */
+	void addContinuationListener(ContinuationListener listener);
+	
+	/* ------------------------------------------------------------ */
+	/** Set a request attribute.
+	 * This method is a convenience method to call the {@link ServletRequest#setAttribute(String, Object)}
+	 * method on the associated request object.
+	 * This is a thread safe call and may be called by any thread.
+	 * @param name the attribute name
+	 * @param attribute the attribute value
+	 */
+	public void setAttribute(String name, Object attribute);
+	
+	/* ------------------------------------------------------------ */
+	/** Get a request attribute.
+	 * This method is a convenience method to call the {@link ServletRequest#getAttribute(String)}
+	 * method on the associated request object.
+	 * This is a thread safe call and may be called by any thread.
+	 * @param name the attribute name
+	 * @return the attribute value
+	 */
+	public Object getAttribute(String name);
+	
+	/* ------------------------------------------------------------ */
+	/** Remove a request attribute.
+	 * This method is a convenience method to call the {@link ServletRequest#removeAttribute(String)}
+	 * method on the associated request object.
+	 * This is a thread safe call and may be called by any thread.
+	 * @param name the attribute name
+	 */
+	public void removeAttribute(String name);
+	
+	/* ------------------------------------------------------------ */
+	/**
+	 * Undispatch the request.
+	 * <p>
+	 * This method can be called on a suspended continuation in order
+	 * to exit the dispatch to the filter/servlet by throwing a {@link ContinuationThrowable}
+	 * which is caught either by the container or the {@link ContinuationFilter}.
+	 * This is an alternative to simply returning from the dispatch in the case
+	 * where filters in the filter chain may not be prepared to handle a suspended
+	 * request.
+	 * </p>
+	 * This method should only be used as a last resort and a normal return is a prefereable
+	 * solution if filters can be updated to handle that case.
+	 * 
+	 * @throws ContinuationThrowable thrown if the request is suspended. The instance of the 
+	 * exception may be reused on subsequent calls, so the stack frame may not be accurate.
+	 */
+	public void undispatch() throws ContinuationThrowable;
 }
diff -r 4de7f6e9c453 -r 1fc8ee20cb18 src/org/eclipse/jetty/server/AsyncContinuation.java
--- a/src/org/eclipse/jetty/server/AsyncContinuation.java	Sun Oct 09 02:08:40 2016 -0600
+++ b/src/org/eclipse/jetty/server/AsyncContinuation.java	Sun Oct 09 03:23:55 2016 -0600
@@ -340,59 +340,6 @@
 	}
 
 	/* ------------------------------------------------------------ */
-	/* (non-Javadoc)
-	 * @see javax.servlet.ServletRequest#suspend(long)
-	 */
-	private void doSuspend(final ServletContext context,
-			final ServletRequest request,
-			final ServletResponse response)
-	{
-		synchronized (this)
-		{
-			switch(_state)
-			{
-				case __DISPATCHED:
-				case __REDISPATCHED:
-					_resumed=false;
-					_expired=false;
-
-					if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext())
-						_event=new AsyncEventState(context,request,response);
-					else
-					{
-						_event._dispatchContext=null;
-						_event._pathInContext=null;
-					}
-					_state=__ASYNCSTARTED;
-					List<AsyncListener> recycle=_lastAsyncListeners;
-					_lastAsyncListeners=_asyncListeners;
-					_asyncListeners=recycle;
-					if (_asyncListeners!=null)
-						_asyncListeners.clear();
-					break;
-
-				default:
-					throw new IllegalStateException(this.getStatusString());
-			}
-		}
-		
-		if (_lastAsyncListeners!=null)
-		{
-			for (AsyncListener listener : _lastAsyncListeners)
-			{
-				try
-				{
-					listener.onStartAsync(_event);
-				}
-				catch(Exception e)
-				{
-					LOG.warn("",e);
-				}
-			}
-		}
-	}
-
-	/* ------------------------------------------------------------ */
 	/**
 	 * Signal that the HttpConnection has finished handling the request.
 	 * For blocking connectors, this call may block if the request has
@@ -966,54 +913,6 @@
 	}
 	
 
-
-	/* ------------------------------------------------------------ */
-	protected void startAsync(final ServletContext context,
-			final ServletRequest request,
-			final ServletResponse response)
-	{
-		synchronized (this)
-		{
-			_responseWrapped=!(response instanceof Response);
-			doSuspend(context,request,response);
-			if (request instanceof HttpServletRequest)
-			{
-				_event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
-			}
-		}
-	}
-
-	/* ------------------------------------------------------------ */
-	protected void startAsync()
-	{
-		_responseWrapped=false;
-		_continuation=false;
-		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());  
-	}
-
-	
-	/* ------------------------------------------------------------ */
-	/**
-	 * @see Continuation#suspend()
-	 */
-	public void suspend(ServletResponse response)
-	{
-		_continuation=true;
-		_responseWrapped=!(response instanceof Response);
-		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); 
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * @see Continuation#suspend()
-	 */
-	public void suspend()
-	{
-		_responseWrapped=false;
-		_continuation=true;
-		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());       
-	}
-
 	/* ------------------------------------------------------------ */
 	/**
 	 * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
diff -r 4de7f6e9c453 -r 1fc8ee20cb18 src/org/eclipse/jetty/server/Request.java
--- a/src/org/eclipse/jetty/server/Request.java	Sun Oct 09 02:08:40 2016 -0600
+++ b/src/org/eclipse/jetty/server/Request.java	Sun Oct 09 03:23:55 2016 -0600
@@ -1750,19 +1750,13 @@
 	/* ------------------------------------------------------------ */
 	public AsyncContext startAsync() throws IllegalStateException
 	{
-		if (!_asyncSupported)
-			throw new IllegalStateException("!asyncSupported");
-		_async.startAsync();
-		return _async;
+		throw new UnsupportedOperationException();
 	}
 
 	/* ------------------------------------------------------------ */
 	public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
 	{
-		if (!_asyncSupported)
-			throw new IllegalStateException("!asyncSupported");
-		_async.startAsync(_context,servletRequest,servletResponse);
-		return _async;
+		throw new UnsupportedOperationException();
 	}
 
 	/* ------------------------------------------------------------ */