# HG changeset patch # User alanb # Date 1552939145 0 # Node ID 3519688a4e4d0e2af50ac5491ce79988633456e1 # Parent adcdd45830a0633b3a72bcc5c7c6283d22977933 More improvements to connection reset handling diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java Mon Mar 18 19:59:05 2019 +0000 @@ -78,7 +78,7 @@ */ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImpl { - private static final NativeDispatcher nd = new SocketDispatcher(true); + private static final NativeDispatcher nd = new SocketDispatcher(); // The maximum number of bytes to read/write per syscall to avoid needing // a huge buffer from the temporary buffer cache diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Mon Mar 18 19:59:05 2019 +0000 @@ -52,6 +52,7 @@ import java.util.Set; import java.util.concurrent.locks.ReentrantLock; +import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.ext.ExtendedSocketOptions; import sun.net.util.SocketExceptions; @@ -356,6 +357,8 @@ } else { n = IOUtil.read(fd, buf, -1, nd); } + } catch (ConnectionResetException e) { + throw new IOException(e.getMessage()); } finally { endRead(blocking, n > 0); if (n <= 0 && isInputClosed) @@ -391,6 +394,8 @@ } else { n = IOUtil.read(fd, dsts, offset, length, nd); } + } catch (ConnectionResetException e) { + throw new IOException(e.getMessage()); } finally { endRead(blocking, n > 0); if (n <= 0 && isInputClosed) diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java --- a/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/unix/classes/sun/nio/ch/SocketDispatcher.java Mon Mar 18 19:59:05 2019 +0000 @@ -34,26 +34,28 @@ */ class SocketDispatcher extends NativeDispatcher { - private final boolean detectConnectionReset; + SocketDispatcher() { } - SocketDispatcher(boolean detectConnectionReset) { - this.detectConnectionReset = detectConnectionReset; - } - - SocketDispatcher() { - this(false); + /** + * Reads up to len bytes from a socket with special handling for "connection + * reset". + * + * @throws sun.net.ConnectionResetException if connection reset is detected + * @throws IOException if another I/O error occurs + */ + int read(FileDescriptor fd, long address, int len) throws IOException { + return read0(fd, address, len); } - int read(FileDescriptor fd, long address, int len) throws IOException { - if (detectConnectionReset) { - return read0(fd, address, len); - } else { - return FileDispatcherImpl.read0(fd, address, len); - } - } - + /** + * Scattering read from a socket into len buffers with special handling for + * "connection reset". + * + * @throws sun.net.ConnectionResetException if connection reset is detected + * @throws IOException if another I/O error occurs + */ long readv(FileDescriptor fd, long address, int len) throws IOException { - return FileDispatcherImpl.readv0(fd, address, len); + return readv0(fd, address, len); } int write(FileDescriptor fd, long address, int len) throws IOException { @@ -74,16 +76,12 @@ // -- Native methods -- - /** - * Reads up to len bytes from a socket with special handling for "connection - * reset". - * - * @throws sun.net.ConnectionResetException if connection reset is detected - * @throws IOException if another I/O error occurs - */ private static native int read0(FileDescriptor fd, long address, int len) throws IOException; + private static native long readv0(FileDescriptor fd, long address, int len) + throws IOException; + static { IOUtil.load(); } diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java --- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Mon Mar 18 19:59:05 2019 +0000 @@ -31,6 +31,8 @@ import java.util.concurrent.*; import java.io.IOException; import java.io.FileDescriptor; + +import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.util.SocketExceptions; import sun.security.action.GetPropertyAction; @@ -415,6 +417,8 @@ enableReading(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); + if (x instanceof ConnectionResetException) + x = new IOException(x.getMessage()); exc = x; } finally { // restart poll in case of concurrent write @@ -546,6 +550,8 @@ } catch (Throwable x) { if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); + if (x instanceof ConnectionResetException) + x = new IOException(x.getMessage()); exc = x; } finally { if (!pending) diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/unix/native/libnio/ch/SocketDispatcher.c --- a/src/java.base/unix/native/libnio/ch/SocketDispatcher.c Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/unix/native/libnio/ch/SocketDispatcher.c Mon Mar 18 19:59:05 2019 +0000 @@ -24,6 +24,7 @@ */ #include + #include #include #include "jni.h" @@ -47,3 +48,18 @@ return convertReturnVal(env, n, JNI_TRUE); } } + + JNIEXPORT jlong JNICALL + Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, + jobject fdo, jlong address, jint len) + { + jint fd = fdval(env, fdo); + struct iovec *iov = (struct iovec *)jlong_to_ptr(address); + jlong n = readv(fd, iov, len); + if ((n == -1) && (errno == ECONNRESET || errno == EPIPE)) { + JNU_ThrowByName(env, "sun/net/ConnectionResetException", "Connection reset"); + return IOS_THROWN; + } else { + return convertLongReturnVal(env, n, JNI_TRUE); + } + } diff -r adcdd45830a0 -r 3519688a4e4d src/java.base/windows/classes/sun/nio/ch/SocketDispatcher.java --- a/src/java.base/windows/classes/sun/nio/ch/SocketDispatcher.java Sat Mar 16 21:00:45 2019 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/SocketDispatcher.java Mon Mar 18 19:59:05 2019 +0000 @@ -33,11 +33,8 @@ */ class SocketDispatcher extends NativeDispatcher { - SocketDispatcher() { } - SocketDispatcher(boolean ignore) { } - int read(FileDescriptor fd, long address, int len) throws IOException { return read0(fd, address, len); }