diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index e2460cda164..5871d8f5abb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -147,6 +147,7 @@ public class HttpChannelState private boolean _asyncWritePossible; private long _timeoutMs = DEFAULT_TIMEOUT; private AsyncContextEvent _event; + private Thread _onTimeoutThread; protected HttpChannelState(HttpChannel channel) { @@ -573,7 +574,10 @@ public class HttpChannelState switch (_requestState) { case ASYNC: + break; case EXPIRING: + if (Thread.currentThread() != _onTimeoutThread) + throw new IllegalStateException(this.getStatusStringLocked()); break; default: throw new IllegalStateException(this.getStatusStringLocked()); @@ -637,39 +641,50 @@ public class HttpChannelState throw new IllegalStateException(toStringLocked()); event = _event; listeners = _asyncListeners; + _onTimeoutThread = Thread.currentThread(); } - if (listeners != null) + try { - Runnable task = new Runnable() + if (listeners != null) { - @Override - public void run() + Runnable task = new Runnable() { - for (AsyncListener listener : listeners) + @Override + public void run() { - try + for (AsyncListener listener : listeners) { - listener.onTimeout(event); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener, x); - else - LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener); + try + { + listener.onTimeout(event); + } + catch (Throwable x) + { + if (LOG.isDebugEnabled()) + LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener, x); + else + LOG.warn("{} while invoking onTimeout listener {}", x.toString(), listener); + } } } - } - @Override - public String toString() - { - return "onTimeout"; - } - }; + @Override + public String toString() + { + return "onTimeout"; + } + }; - runInContext(event, task); + runInContext(event, task); + } + } + finally + { + synchronized (this) + { + _onTimeoutThread = null; + } } } @@ -686,6 +701,11 @@ public class HttpChannelState switch (_requestState) { case EXPIRING: + if (Thread.currentThread() != _onTimeoutThread) + throw new IllegalStateException(this.getStatusStringLocked()); + _requestState = _sendError ? RequestState.BLOCKING : RequestState.COMPLETE; + break; + case ASYNC: _requestState = _sendError ? RequestState.BLOCKING : RequestState.COMPLETE; break; diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java index 7f15a0e2c82..54e68b347a9 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java @@ -230,8 +230,8 @@ public class QoSFilter implements Filter } catch (IllegalStateException x) { - LOG.warn("Unable to resume suspended dispatch", x); - continue; + if (LOG.isDebugEnabled()) + LOG.debug("dispatch failed", x); } } } @@ -356,12 +356,12 @@ public class QoSFilter implements Filter } @Override - public void onStartAsync(AsyncEvent event) throws IOException + public void onStartAsync(AsyncEvent event) { } @Override - public void onComplete(AsyncEvent event) throws IOException + public void onComplete(AsyncEvent event) { } @@ -377,7 +377,7 @@ public class QoSFilter implements Filter } @Override - public void onError(AsyncEvent event) throws IOException + public void onError(AsyncEvent event) { } }