Fix #6227 Async timeout dispatch race Only allow the thread calling onTimeout to call dispatch and complete once timeout has expired. Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
2f19c67b41
commit
ad6d23fc68
|
@ -155,6 +155,7 @@ public class HttpChannelState
|
|||
private boolean _asyncWritePossible;
|
||||
private long _timeoutMs = DEFAULT_TIMEOUT;
|
||||
private AsyncContextEvent _event;
|
||||
private Thread _onTimeoutThread;
|
||||
|
||||
protected HttpChannelState(HttpChannel channel)
|
||||
{
|
||||
|
@ -582,7 +583,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());
|
||||
|
@ -646,36 +650,47 @@ 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)
|
||||
{
|
||||
LOG.warn("{} while invoking onTimeout listener {}", x, listener, x);
|
||||
try
|
||||
{
|
||||
listener.onTimeout(event);
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.warn("{} while invoking onTimeout listener {}", x, listener, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "onTimeout";
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "onTimeout";
|
||||
}
|
||||
};
|
||||
|
||||
runInContext(event, task);
|
||||
runInContext(event, task);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
_onTimeoutThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,6 +707,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;
|
||||
|
|
|
@ -235,7 +235,8 @@ public class QoSFilter implements Filter
|
|||
}
|
||||
catch (IllegalStateException x)
|
||||
{
|
||||
LOG.warn(x);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue