I've created a class that implements ReadListener and WriteListener, called EchoListener. It's supposed to echo input to the output stream using the non-blocking IO api. Most of the time it works, but in one case I'm seeing requests hang.
I've debugged this a bit and here's what seems to be triggering the request to hang. 1.) A request comes in. 2.) My servlet handles it and set's up the read / write listeners. 3.) The write listener's onWritePossible method is called. 4.) onWritePossible starts to echo data, reading while it can and writing that data. In the case that hangs, all of the data is echoed by the call to onWritePossible. 5.) The request has no more data to read, so the async context should be completed. In my code, this is triggered by the call to "onAllDataRead()", but in this case "onAllDataRead()" is never called. Debugging this further and looking into the code for CoyoteAdapter, it appears that "onAllDataRead()" is not called if the request is finished during the call to "onWritePossible". if (res.getWriteListener() != null && status == SocketStatus.OPEN_WRITE) { ... try { Thread.currentThread().setContextClassLoader(newCL); res.onWritePossible(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); res.getWriteListener().onError(t); throw t; } finally { Thread.currentThread().setContextClassLoader(oldCL); } success = true; } This is in contrast to a call to "onDataAvailable", which triggers a check and possibly a call to "onAllDataRead()". else if (req.getReadListener() != null && status == SocketStatus.OPEN_READ) { ... try { Thread.currentThread().setContextClassLoader(newCL); req.getReadListener().onDataAvailable(); if (request.isFinished()) { req.getReadListener().onAllDataRead(); } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); req.getReadListener().onError(t); throw t; } finally { Thread.currentThread().setContextClassLoader(oldCL); } success = true; } My question, should the "onAllDataRead()" method be called in this situation? The spec says "onAllDataRead method is invoked when you have finished reading all the data for the ServletRequest for which the listener was registered.", however it's referring to the ReadListener and in this case "onWritePossible" (i.e. my WriteListener) is reading the data. Thanks Dan PS. I have a test case which I can include to replicate the behavior if needed. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org