458745 Async ISE in async Echo
The HttpOutput class was throwing an ISE if it was dispatched when PENDING or UNREADY. However this can occur when it has been dispatched, but a prior call to onDataAvailable() does output after calling isReady(). The HttpOutput now does not enforce that part of the state machine and defers to the application correctly calling isReady()
This commit is contained in:
parent
9fd3a9342f
commit
f65a7db8c5
|
@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
public class AsyncEchoServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
|
@ -62,17 +64,22 @@ public class AsyncEchoServlet extends HttpServlet
|
|||
@Override
|
||||
public void onDataAvailable() throws IOException
|
||||
{
|
||||
onWritePossible();
|
||||
handleAsyncIO();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllDataRead() throws IOException
|
||||
{
|
||||
onWritePossible();
|
||||
handleAsyncIO();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWritePossible() throws IOException
|
||||
{
|
||||
handleAsyncIO();
|
||||
}
|
||||
|
||||
private void handleAsyncIO() throws IOException
|
||||
{
|
||||
// This method is called:
|
||||
// 1) after first registering a WriteListener (ready for first write)
|
||||
|
@ -81,8 +88,17 @@ public class AsyncEchoServlet extends HttpServlet
|
|||
// 4) from an input callback
|
||||
|
||||
// We should try to read, only if we are able to write!
|
||||
while (output.isReady() && input.isReady())
|
||||
while (true)
|
||||
{
|
||||
if (!output.isReady())
|
||||
// Don't even try to read anything until it is possible to write something,
|
||||
// when onWritePossible will be called
|
||||
break;
|
||||
|
||||
if (!input.isReady())
|
||||
// Nothing available to read, so wait for another call to onDataAvailable
|
||||
break;
|
||||
|
||||
int read = input.read(buffer);
|
||||
if (read<0)
|
||||
{
|
||||
|
@ -100,7 +116,7 @@ public class AsyncEchoServlet extends HttpServlet
|
|||
@Override
|
||||
public void onError(Throwable failure)
|
||||
{
|
||||
failure.printStackTrace();
|
||||
new Throwable("onError",failure).printStackTrace();
|
||||
asyncContext.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.JavaUtilLog
|
||||
#org.eclipse.jetty.util.log.javautil.PROPERTIES=java-util-logging.properties
|
||||
#org.eclipse.jetty.util.log.SOURCE=true
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
org.eclipse.jetty.STACKS=true
|
||||
#org.eclipse.jetty.LEVEL=INFO
|
||||
#org.eclipse.jetty.STACKS=true
|
||||
#org.eclipse.jetty.STACKS=false
|
||||
#org.eclipse.jetty.io.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
|
||||
|
|
|
@ -926,6 +926,8 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
// occurred, we need to call onWritePossible to tell async
|
||||
// producer that the last write completed.
|
||||
// So fall through
|
||||
case PENDING:
|
||||
case UNREADY:
|
||||
case READY:
|
||||
try
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue