430273 Cancel async timeout breaks volatile link to avoid race with slow expire

This commit is contained in:
Greg Wilkins 2014-03-14 10:27:32 +11:00
parent 2b59cd305d
commit d76c786803
6 changed files with 30 additions and 22 deletions

View File

@ -29,14 +29,14 @@ import javax.servlet.ServletResponse;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.util.thread.Scheduler;
public class AsyncContextEvent extends AsyncEvent
public class AsyncContextEvent extends AsyncEvent implements Runnable
{
final private Context _context;
final private AsyncContextState _asyncContext;
volatile HttpChannelState _state;
private volatile HttpChannelState _state;
private ServletContext _dispatchContext;
private String _dispatchPath;
private Scheduler.Task _timeoutTask;
private volatile Scheduler.Task _timeoutTask;
private Throwable _throwable;
public AsyncContextEvent(Context context,AsyncContextState asyncContext, HttpChannelState state, Request baseRequest, ServletRequest request, ServletResponse response)
@ -143,6 +143,7 @@ public class AsyncContextEvent extends AsyncEvent
public void completed()
{
_timeoutTask=null;
_asyncContext.reset();
}
@ -151,4 +152,13 @@ public class AsyncContextEvent extends AsyncEvent
return _state;
}
@Override
public void run()
{
Scheduler.Task task=_timeoutTask;
_timeoutTask=null;
if (task!=null)
_state.expired();
}
}

View File

@ -307,7 +307,8 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
_response.setStatusWithReason(500,reason);
ErrorHandler eh = _state.getContextHandler().getErrorHandler();
ErrorHandler eh = ErrorHandler.getErrorHandler(getServer(),_state.getContextHandler());
if (eh instanceof ErrorHandler.ErrorPageMapper)
{
String error_page=((ErrorHandler.ErrorPageMapper)eh).getErrorPage((HttpServletRequest)_state.getAsyncContextEvent().getSuppliedRequest());

View File

@ -537,7 +537,7 @@ public class HttpChannelState
{
Scheduler scheduler = _channel.getScheduler();
if (scheduler!=null && _timeoutMs>0)
_event.setTimeoutTask(scheduler.schedule(new AsyncTimeout(),_timeoutMs,TimeUnit.MILLISECONDS));
_event.setTimeoutTask(scheduler.schedule(_event,_timeoutMs,TimeUnit.MILLISECONDS));
}
protected void cancelTimeout()
@ -691,13 +691,4 @@ public class HttpChannelState
_channel.execute(_channel);
}
public class AsyncTimeout implements Runnable
{
@Override
public void run()
{
HttpChannelState.this.expired();
}
}
}

View File

@ -581,13 +581,7 @@ public class Response implements HttpServletResponse
code!=SC_PARTIAL_CONTENT &&
code>=SC_OK)
{
ErrorHandler error_handler = null;
ContextHandler.Context context = request.getContext();
if (context!=null)
error_handler=context.getContextHandler().getErrorHandler();
if (error_handler==null)
error_handler = _channel.getServer().getBean(ErrorHandler.class);
ErrorHandler error_handler = ErrorHandler.getErrorHandler(_channel.getServer(),request.getContext()==null?null:request.getContext().getContextHandler());
if (error_handler!=null)
{
request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code));

View File

@ -36,6 +36,7 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.eclipse.jetty.util.log.Log;
@ -304,4 +305,15 @@ public class ErrorHandler extends AbstractHandler
{
String getErrorPage(HttpServletRequest request);
}
/* ------------------------------------------------------------ */
public static ErrorHandler getErrorHandler(Server server, ContextHandler context)
{
ErrorHandler error_handler=null;
if (context!=null)
error_handler=context.getErrorHandler();
if (error_handler==null && server!=null)
error_handler = server.getBean(ErrorHandler.class);
return error_handler;
}
}

View File

@ -414,7 +414,7 @@
<module>jetty-servlet</module>
<module>jetty-webapp</module>
<module>jetty-spdy</module>
<module>jetty-fcgi</module>
<!--module>jetty-fcgi</module-->
<module>jetty-websocket</module>
<module>jetty-servlets</module>
<module>jetty-util-ajax</module>