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:
Greg Wilkins 2015-12-23 15:07:05 +11:00
parent 9fd3a9342f
commit f65a7db8c5
3 changed files with 24 additions and 6 deletions

View File

@ -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();
}
}

View File

@ -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

View File

@ -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
{