On Tue, Dec 3, 2019 at 10:56 PM Mark Thomas <ma...@apache.org> wrote:
> Hi, > > I've been looking into BZ 63931. The error messages I was expecting to > see were not there. > > The first odd thing I noticed was an NPE here: > > https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java#L310 > > bsh.getSendResult() returned null. That shouldn't happen. > > I added some debug logging and found that the call to writeMessagePart() > on the previous line was returning before the SendResult was populated. > > Tracing the code for writeMessagePart() led me to > SocketWrapperBase.vectoredOperation() > > The issue appears to be that state.start() at > > > https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/net/SocketWrapperBase.java#L1425 > > effectively always does non-blocking writes. If the write buffer is full > (which is the scenario I am testing) 0 bytes are written, the socket is > passed to the Poller and the call returns. > > I hacked in the following code just after the state.start() > > if (block == BlockingMode.BLOCK) { > if (read) { > readPending.acquireUninterruptibly(); > readPending.release(); > } else { > writePending.acquireUninterruptibly(); > writePending.release(); > } > } > > I'm sure that code is wrong. It was just intended as a quick hack to > force the call to block until the write had completed. It had the > desired effect and I started to see the error messages I expected. > > I'm not familiar enough with the asyncIO code yet to know where the best > place to fix this is. Rémy, are you able to help? > I'm not sure about the problem. Is there a test case ? Blocking is also used for HTTP/2 where it seems to work. If the write buffer is full, 0 bytes are written and the socket is indeed passed to the poller but until the operation is complete it is supposed to be blocked here: https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/net/SocketWrapperBase.java#L1430 Since I made the fix here for NIO ( https://github.com/apache/tomcat/commit/f5f2b62670f972fc6a857788084e4352f2d4cd87 ) I may need to do the same loop here however (when writing the buffer it is there): https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/net/NioEndpoint.java#L1493 Rémy