Issue #470 AsyncContextState NPE if called after reset
Added a NOT_ASYNC state to the enum to avoid the null value.
This commit is contained in:
parent
86f3947378
commit
08b528e960
|
@ -51,7 +51,7 @@ public class AsyncContextState implements AsyncContext
|
|||
{
|
||||
HttpChannelState state=_state;
|
||||
if (state==null)
|
||||
throw new IllegalStateException("AsyncContext completed");
|
||||
throw new IllegalStateException("AsyncContext completed and/or Request lifecycle recycled");
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ public class HttpChannelState
|
|||
*/
|
||||
public enum Async
|
||||
{
|
||||
NOT_ASYNC,
|
||||
STARTED, // AsyncContext.startAsync() has been called
|
||||
DISPATCH, //
|
||||
COMPLETE, // AsyncContext.complete() has been called
|
||||
|
@ -109,7 +110,7 @@ public class HttpChannelState
|
|||
{
|
||||
_channel=channel;
|
||||
_state=State.IDLE;
|
||||
_async=null;
|
||||
_async=Async.NOT_ASYNC;
|
||||
_initial=true;
|
||||
}
|
||||
|
||||
|
@ -216,33 +217,30 @@ public class HttpChannelState
|
|||
return Action.WRITE_CALLBACK;
|
||||
}
|
||||
|
||||
if (_async!=null)
|
||||
switch(_async)
|
||||
{
|
||||
Async async=_async;
|
||||
switch(async)
|
||||
{
|
||||
case COMPLETE:
|
||||
_state=State.COMPLETING;
|
||||
return Action.COMPLETE;
|
||||
case DISPATCH:
|
||||
_state=State.DISPATCHED;
|
||||
_async=null;
|
||||
return Action.ASYNC_DISPATCH;
|
||||
case EXPIRING:
|
||||
break;
|
||||
case EXPIRED:
|
||||
_state=State.DISPATCHED;
|
||||
_async=null;
|
||||
return Action.ERROR_DISPATCH;
|
||||
case STARTED:
|
||||
return Action.WAIT;
|
||||
case ERRORING:
|
||||
_state=State.DISPATCHED;
|
||||
return Action.ASYNC_ERROR;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(getStatusStringLocked());
|
||||
}
|
||||
case COMPLETE:
|
||||
_state=State.COMPLETING;
|
||||
return Action.COMPLETE;
|
||||
case DISPATCH:
|
||||
_state=State.DISPATCHED;
|
||||
_async=Async.NOT_ASYNC;
|
||||
return Action.ASYNC_DISPATCH;
|
||||
case EXPIRING:
|
||||
break;
|
||||
case EXPIRED:
|
||||
_state=State.DISPATCHED;
|
||||
_async=Async.NOT_ASYNC;
|
||||
return Action.ERROR_DISPATCH;
|
||||
case STARTED:
|
||||
return Action.WAIT;
|
||||
case ERRORING:
|
||||
_state=State.DISPATCHED;
|
||||
return Action.ASYNC_ERROR;
|
||||
case NOT_ASYNC:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(getStatusStringLocked());
|
||||
}
|
||||
|
||||
return Action.WAIT;
|
||||
|
@ -264,7 +262,7 @@ public class HttpChannelState
|
|||
|
||||
try(Locker.Lock lock= _locker.lock())
|
||||
{
|
||||
if (_state!=State.DISPATCHED || _async!=null)
|
||||
if (_state!=State.DISPATCHED || _async!=Async.NOT_ASYNC)
|
||||
throw new IllegalStateException(this.getStatusStringLocked());
|
||||
|
||||
_async=Async.STARTED;
|
||||
|
@ -346,78 +344,75 @@ public class HttpChannelState
|
|||
throw new IllegalStateException(this.getStatusStringLocked());
|
||||
}
|
||||
|
||||
if (_async!=null)
|
||||
_initial=false;
|
||||
switch(_async)
|
||||
{
|
||||
_initial=false;
|
||||
switch(_async)
|
||||
{
|
||||
case COMPLETE:
|
||||
_state=State.COMPLETING;
|
||||
_async=null;
|
||||
action=Action.COMPLETE;
|
||||
break;
|
||||
case COMPLETE:
|
||||
_state=State.COMPLETING;
|
||||
_async=Async.NOT_ASYNC;
|
||||
action=Action.COMPLETE;
|
||||
break;
|
||||
|
||||
case DISPATCH:
|
||||
_state=State.DISPATCHED;
|
||||
_async=null;
|
||||
action=Action.ASYNC_DISPATCH;
|
||||
break;
|
||||
case DISPATCH:
|
||||
_state=State.DISPATCHED;
|
||||
_async=Async.NOT_ASYNC;
|
||||
action=Action.ASYNC_DISPATCH;
|
||||
break;
|
||||
|
||||
case EXPIRED:
|
||||
_state=State.DISPATCHED;
|
||||
_async=null;
|
||||
action = Action.ERROR_DISPATCH;
|
||||
break;
|
||||
case EXPIRED:
|
||||
_state=State.DISPATCHED;
|
||||
_async=Async.NOT_ASYNC;
|
||||
action = Action.ERROR_DISPATCH;
|
||||
break;
|
||||
|
||||
case STARTED:
|
||||
if (_asyncReadUnready && _asyncReadPossible)
|
||||
{
|
||||
_state=State.ASYNC_IO;
|
||||
_asyncReadUnready=false;
|
||||
action = Action.READ_CALLBACK;
|
||||
}
|
||||
else if (_asyncWrite) // TODO refactor same as read
|
||||
{
|
||||
_asyncWrite=false;
|
||||
_state=State.ASYNC_IO;
|
||||
action=Action.WRITE_CALLBACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule_event=_event;
|
||||
read_interested=_asyncReadUnready;
|
||||
_state=State.ASYNC_WAIT;
|
||||
action=Action.WAIT;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXPIRING:
|
||||
case STARTED:
|
||||
if (_asyncReadUnready && _asyncReadPossible)
|
||||
{
|
||||
_state=State.ASYNC_IO;
|
||||
_asyncReadUnready=false;
|
||||
action = Action.READ_CALLBACK;
|
||||
}
|
||||
else if (_asyncWrite) // TODO refactor same as read
|
||||
{
|
||||
_asyncWrite=false;
|
||||
_state=State.ASYNC_IO;
|
||||
action=Action.WRITE_CALLBACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule_event=_event;
|
||||
read_interested=_asyncReadUnready;
|
||||
_state=State.ASYNC_WAIT;
|
||||
action=Action.WAIT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ERRORING:
|
||||
_state=State.DISPATCHED;
|
||||
action=Action.ASYNC_ERROR;
|
||||
break;
|
||||
case EXPIRING:
|
||||
schedule_event=_event;
|
||||
_state=State.ASYNC_WAIT;
|
||||
action=Action.WAIT;
|
||||
break;
|
||||
|
||||
case ERRORED:
|
||||
_state=State.DISPATCHED;
|
||||
action=Action.ERROR_DISPATCH;
|
||||
_async=null;
|
||||
break;
|
||||
case ERRORING:
|
||||
_state=State.DISPATCHED;
|
||||
action=Action.ASYNC_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
_state=State.COMPLETING;
|
||||
action=Action.COMPLETE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_state=State.COMPLETING;
|
||||
action=Action.COMPLETE;
|
||||
case ERRORED:
|
||||
_state=State.DISPATCHED;
|
||||
action=Action.ERROR_DISPATCH;
|
||||
_async=Async.NOT_ASYNC;
|
||||
break;
|
||||
|
||||
case NOT_ASYNC:
|
||||
_state=State.COMPLETING;
|
||||
action=Action.COMPLETE;
|
||||
break;
|
||||
|
||||
default:
|
||||
_state=State.COMPLETING;
|
||||
action=Action.COMPLETE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,7 +656,7 @@ public class HttpChannelState
|
|||
aListeners=_asyncListeners;
|
||||
event=_event;
|
||||
_state=State.COMPLETED;
|
||||
_async=null;
|
||||
_async=Async.NOT_ASYNC;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -720,7 +715,7 @@ public class HttpChannelState
|
|||
}
|
||||
_asyncListeners=null;
|
||||
_state=State.IDLE;
|
||||
_async=null;
|
||||
_async=Async.NOT_ASYNC;
|
||||
_initial=true;
|
||||
_asyncReadPossible=_asyncReadUnready=false;
|
||||
_asyncWrite=false;
|
||||
|
@ -744,7 +739,7 @@ public class HttpChannelState
|
|||
}
|
||||
_asyncListeners=null;
|
||||
_state=State.UPGRADED;
|
||||
_async=null;
|
||||
_async=Async.NOT_ASYNC;
|
||||
_initial=true;
|
||||
_asyncReadPossible=_asyncReadUnready=false;
|
||||
_asyncWrite=false;
|
||||
|
@ -834,7 +829,7 @@ public class HttpChannelState
|
|||
try(Locker.Lock lock= _locker.lock())
|
||||
{
|
||||
if (_state==State.DISPATCHED)
|
||||
return _async!=null;
|
||||
return _async!=Async.NOT_ASYNC;
|
||||
return _async==Async.STARTED || _async==Async.EXPIRING;
|
||||
}
|
||||
}
|
||||
|
@ -843,7 +838,7 @@ public class HttpChannelState
|
|||
{
|
||||
try(Locker.Lock lock= _locker.lock())
|
||||
{
|
||||
return !_initial || _async!=null;
|
||||
return !_initial || _async!=Async.NOT_ASYNC;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue