Possible network issue

robert engels rengels at ix.netcom.com
Tue Nov 7 06:32:12 UTC 2023


Hi,

I would ordinarily send this to the net list, but I think this code was changed to support VT - using Nio behind the scenes for socket writes.

Essentially, I am receiving the following exception under heavy load (exhausting the kernel network buffers):

java.net.SocketException: No buffer space available
        at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method)
        at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:62)
        at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:394)
        at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:410)
        at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
        at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:819)
        at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1195)
        at robaho.net.httpserver.HttpConnection$ActivityTimerOutputStream.write(HttpConnection.java:189)
        at java.base/java.io.BufferedOutputStream.implWrite(BufferedOutputStream.java:217)
        at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:200)
        at robaho.net.httpserver.FixedLengthOutputStream.write(FixedLengthOutputStream.java:76)
        at robaho.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:487)
        at SimpleFileServer$DevNullHandler.handle(SimpleFileServer.java:94)
        at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98)
        at robaho.net.httpserver.AuthFilter.doFilter(AuthFilter.java:77)
        at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:101)
        at robaho.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:570)
        at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98)
        at robaho.net.httpserver.LogFilter.doFilter(LogFilter.java:44)
        at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:101)
        at robaho.net.httpserver.ServerImpl$Exchange.runPerRequest(ServerImpl.java:550)
        at robaho.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:367)
        at java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
        at java.base/java.lang.VirtualThread.run(VirtualThread.java:311)

using a blocking socket.

Looking at the code, I see in NioSocketImpl.java:

    private int implWrite(byte[] b, int off, int len) throws IOException {
        int n = 0;
        FileDescriptor fd = beginWrite();
        try {
            configureNonBlockingIfNeeded(fd, false);
            n = tryWrite(fd, b, off, len);
            while (IOStatus.okayToRetry(n) && isOpen()) {
                park(fd, Net.POLLOUT);
                n = tryWrite(fd, b, off, len);
            }
            return n;
        } catch (InterruptedIOException e) {
            throw e;
        } catch (IOException ioe) {
            // throw SocketException to maintain compatibility
            throw asSocketException(ioe);
        } finally {
            endWrite(n > 0);
        }
    }

so the socket is put into non-blocking mode to perform the write.

The issue is that the “No buffer space available” is only thrown for a non-blocking write - to signal that there is no kernel network buffer space available - at the moment - in a blocking write() it should block until space is available with TCP.

To maintain the semantics of a blocking write, this should be retried until completion in this loop.

Note, this is under OSX and that could be affecting this behavior.



More information about the loom-dev mailing list