From af16ded69bbe3ae345b94c0683753578ba8d8161 Mon Sep 17 00:00:00 2001 From: michaelm Date: Wed, 6 Aug 2014 16:51:30 +0100 Subject: [PATCH] 8053963: (dc) Use DatagramChannel.receive() instead of read() in connect() Reviewed-by: chegar, alanb --- .../classes/java/net/DatagramSocket.java | 27 +++++---- .../sun/nio/ch/DatagramChannelImpl.java | 2 +- .../net/AbstractPlainDatagramSocketImpl.c | 55 +++++++++++++++---- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/share/classes/java/net/DatagramSocket.java b/src/share/classes/java/net/DatagramSocket.java index bbe3e1bf4..2fdabb597 100644 --- a/src/share/classes/java/net/DatagramSocket.java +++ b/src/share/classes/java/net/DatagramSocket.java @@ -769,6 +769,7 @@ class DatagramSocket implements java.io.Closeable { } // end of while } } + DatagramPacket tmp = null; if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect @@ -793,11 +794,13 @@ class DatagramSocket implements java.io.Closeable { if ((!connectedAddress.equals(peekAddress)) || (connectedPort != peekPort)) { // throw the packet away and silently continue - DatagramPacket tmp = new DatagramPacket( + tmp = new DatagramPacket( new byte[1024], 1024); getImpl().receive(tmp); if (explicitFilter) { - bytesLeftToFilter -= tmp.getLength(); + if (checkFiltering(tmp)) { + stop = true; + } } } else { stop = true; @@ -807,18 +810,22 @@ class DatagramSocket implements java.io.Closeable { // If the security check succeeds, or the datagram is // connected then receive the packet getImpl().receive(p); - if (explicitFilter) { - bytesLeftToFilter -= p.getLength(); - if (bytesLeftToFilter <= 0) { - explicitFilter = false; - } else { - // break out of filter, if there is no more data queued - explicitFilter = getImpl().dataAvailable() > 0; - } + if (explicitFilter && tmp == null) { + // packet was not filtered, account for it here + checkFiltering(p); } } } + private boolean checkFiltering(DatagramPacket p) throws SocketException { + bytesLeftToFilter -= p.getLength(); + if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { + explicitFilter = false; + return true; + } + return false; + } + /** * Gets the local address to which the socket is bound. * diff --git a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java index 4a73c99bc..0022e30e9 100644 --- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -768,7 +768,7 @@ class DatagramChannelImpl } do { tmpBuf.clear(); - } while (read(tmpBuf) > 0); + } while (receive(tmpBuf) != null); } finally { if (blocking) { configureBlocking(true); diff --git a/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c b/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c index 7244e664c..dd2c7e8a9 100644 --- a/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c +++ b/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c @@ -32,9 +32,11 @@ #include "java_net_AbstractPlainDatagramSocketImpl.h" -static jfieldID IO_fd_fdID; +static jfieldID IO_fd_fdID = NULL; +static jfieldID apdsi_fdID = NULL; -static jfieldID apdsi_fdID; +static jfieldID apdsi_fd1ID = NULL; +static jclass two_stacks_clazz = NULL; /* @@ -48,10 +50,21 @@ Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", "Ljava/io/FileDescriptor;"); CHECK_NULL(apdsi_fdID); - IO_fd_fdID = NET_GetFileDescriptorID(env); CHECK_NULL(IO_fd_fdID); + two_stacks_clazz = (*env)->FindClass(env, "java/net/TwoStacksPlainDatagramSocketImpl"); + CHECK_NULL(two_stacks_clazz); + + /* Handle both TwoStacks and DualStack here */ + + if (JNU_Equals(env, cls, two_stacks_clazz)) { + /* fd1 present only in TwoStack.. */ + apdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fd1ID); + } + JNU_CHECK_EXCEPTION(env); } @@ -63,20 +76,38 @@ Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable (JNIEnv *env, jobject this) { SOCKET fd; - int retval; - + SOCKET fd1; + int rv = -1, rv1 = -1; jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - "Socket closed"); - return -1; + if (!IS_NULL(fdObj)) { + int retval = 0; + fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); + rv = ioctlsocket(fd, FIONREAD, &retval); + if (retval > 0) { + return retval; + } + } + + if (!IS_NULL(apdsi_fd1ID)) { + /* TwoStacks */ + jobject fd1Obj = (*env)->GetObjectField(env, this, apdsi_fd1ID); + if (!IS_NULL(fd1Obj)) { + int retval = 0; + fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID); + rv1 = ioctlsocket(fd1, FIONREAD, &retval); + if (retval > 0) { + return retval; + } + } } - fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); - if (ioctlsocket(fd, FIONREAD, &retval) < 0) { + if (rv < 0 && rv1 < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); return -1; } - return retval; + + return 0; } -- GitLab