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