--- old/make/mapfiles/libnet/mapfile-vers 2016-02-24 13:34:27.112280894 +0530 +++ new/make/mapfiles/libnet/mapfile-vers 2016-02-24 13:34:26.992280893 +0530 @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -99,6 +99,9 @@ Java_sun_net_ExtendedOptionsImpl_setFlowOption; Java_sun_net_ExtendedOptionsImpl_getFlowOption; Java_sun_net_ExtendedOptionsImpl_flowSupported; + Java_sun_net_ExtendedOptionsImpl_setQuickAckOption; + Java_sun_net_ExtendedOptionsImpl_getQuickAckOption; + Java_sun_net_ExtendedOptionsImpl_isQuickAckAvailable0; NET_AllocSockaddr; NET_SockaddrToInetAddress; NET_SockaddrEqualsInetAddress; --- old/make/src/native/genconstants/ch/genSocketOptionRegistry.c 2016-02-24 13:34:27.456280899 +0530 +++ new/make/src/native/genconstants/ch/genSocketOptionRegistry.c 2016-02-24 13:34:27.336280898 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,13 @@ #include #endif +#if !defined(SO_QUICKACK) + #if defined(__linux__) + #define SO_QUICKACK 0xC /* Block/reenable quick ACKs. */ + #else + #define SO_QUICKACK 0 + #endif +#endif /** * Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level * socket options to the platform specific level and option. @@ -117,6 +124,7 @@ #endif emit_unspec("ExtendedSocketOption.SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE); + emit_unspec("jdk.net.ExtendedSocketOptions.SO_QUICKACK", SOL_SOCKET, SO_QUICKACK); out(" return map; "); out(" } "); --- old/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java 2016-02-24 13:34:27.808280905 +0530 +++ new/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java 2016-02-24 13:34:27.688280903 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,4 +58,31 @@ */ public static final SocketOption SO_FLOW_SLA = new ExtSocketOption("SO_FLOW_SLA", SocketFlow.class); + + /** + * SO_QUICKACK. + * + *

+ * The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The exact semantics of this + * socket option are socket type and system dependent. + * + *

+ * This socket option usually enable TCP_QUICKACK mode if set or disable + * TCP_QUICKACK mode if cleared. + * + *

+ * In TCP_QUICKACK mode, acks are sent immediately, rather than delayed if + * needed in accordance to normal TCP operation.This flag is not permanent, + * it only enables a switch to or from TCP_QUICKACK mode. + * + *

+ * Subsequent operation of the TCP protocol will once again enter/leave + * TCP_QUICKACK mode depending on internal protocol processing and factors + * such as delayed ack timeouts occurring and data transfer. + * + * @since 9 + */ + public static final SocketOption SO_QUICKACK + = new ExtSocketOption("SO_QUICKACK", Boolean.class); } --- old/src/java.base/share/classes/jdk/net/Sockets.java 2016-02-24 13:34:28.168280910 +0530 +++ new/src/java.base/share/classes/jdk/net/Sockets.java 2016-02-24 13:34:28.048280908 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,6 +253,7 @@ private static void initOptionSets() { boolean flowsupported = ExtendedOptionsImpl.flowSupported(); + boolean quickAckSupported = ExtendedOptionsImpl.isQuickAckAvailable(); // Socket @@ -267,6 +268,9 @@ if (flowsupported) { set.add(ExtendedSocketOptions.SO_FLOW_SLA); } + if (quickAckSupported) { + set.add(ExtendedSocketOptions.SO_QUICKACK); + } set = Collections.unmodifiableSet(set); options.put(Socket.class, set); @@ -289,6 +293,9 @@ if (flowsupported) { set.add(ExtendedSocketOptions.SO_FLOW_SLA); } + if (quickAckSupported) { + set.add(ExtendedSocketOptions.SO_QUICKACK); + } set = Collections.unmodifiableSet(set); options.put(DatagramSocket.class, set); @@ -305,6 +312,9 @@ if (flowsupported) { set.add(ExtendedSocketOptions.SO_FLOW_SLA); } + if (quickAckSupported) { + set.add(ExtendedSocketOptions.SO_QUICKACK); + } set = Collections.unmodifiableSet(set); options.put(MulticastSocket.class, set); } --- old/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java 2016-02-24 13:34:28.520280915 +0530 +++ new/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java 2016-02-24 13:34:28.396280914 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,9 @@ import java.net.*; import jdk.net.*; -import java.io.IOException; import java.io.FileDescriptor; import java.security.PrivilegedAction; import java.security.AccessController; -import java.lang.reflect.Field; -import java.util.Set; -import java.util.HashSet; -import java.util.HashMap; -import java.util.Collections; /** * Contains the native implementation for extended socket options @@ -80,6 +74,19 @@ } private static native void init(); + private static volatile boolean checkedQuickAck; + private static volatile boolean isQuickAckAvailable; + /** + * Tells whether SO_QUICKACK is supported. + * @return + */ + public static boolean isQuickAckAvailable() { + if (!checkedQuickAck) { + isQuickAckAvailable = isQuickAckAvailable0(); + checkedQuickAck = true; + } + return isQuickAckAvailable; + } /* * Extension native implementations @@ -89,4 +96,9 @@ public static native void setFlowOption(FileDescriptor fd, SocketFlow f); public static native void getFlowOption(FileDescriptor fd, SocketFlow f); public static native boolean flowSupported(); + + /* SO_QUICKACK */ + public static native void setQuickAckOption(FileDescriptor fd, boolean on); + public static native Object getQuickAckOption(FileDescriptor fd); + private static native boolean isQuickAckAvailable0(); } --- old/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java 2016-02-24 13:34:28.872280921 +0530 +++ new/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java 2016-02-24 13:34:28.752280919 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -512,6 +512,9 @@ if (ExtendedOptionsImpl.flowSupported()) { set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); } + if (ExtendedOptionsImpl.isQuickAckAvailable()) { + set.add(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + } return Collections.unmodifiableSet(set); } } --- old/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java 2016-02-24 13:34:29.240280926 +0530 +++ new/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java 2016-02-24 13:34:29.116280924 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -242,6 +242,9 @@ if (ExtendedOptionsImpl.flowSupported()) { set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); } + if (ExtendedOptionsImpl.isQuickAckAvailable()) { + set.add(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + } return Collections.unmodifiableSet(set); } } --- old/src/java.base/unix/classes/java/net/PlainSocketImpl.java 2016-02-24 13:34:29.588280931 +0530 +++ new/src/java.base/unix/classes/java/net/PlainSocketImpl.java 2016-02-24 13:34:29.472280930 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.io.FileDescriptor; import java.util.Set; import java.util.HashSet; -import java.util.Collections; import jdk.net.*; import static sun.net.ExtendedOptionsImpl.*; @@ -59,7 +58,13 @@ protected void setOption(SocketOption name, T value) throws IOException { if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { - super.setOption(name, value); + if (!name.equals(ExtendedSocketOptions.SO_QUICKACK)) { + super.setOption(name, value); + } else if (isQuickAckAvailable()) { + setQuickAckOption(getFileDescriptor(), ((Boolean)value)); + } else { + throw new UnsupportedOperationException("unsupported option"); + } } else { if (getSocket() == null || !flowSupported()) { throw new UnsupportedOperationException("unsupported option"); @@ -76,7 +81,13 @@ @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { - return super.getOption(name); + if (!name.equals(ExtendedSocketOptions.SO_QUICKACK)) { + return super.getOption(name); + } else if (isQuickAckAvailable()) { + return (T) getQuickAckOption(getFileDescriptor()); + } else { + throw new UnsupportedOperationException("unsupported option"); + } } if (getSocket() == null || !flowSupported()) { throw new UnsupportedOperationException("unsupported option"); @@ -97,6 +108,9 @@ if (getSocket() != null && flowSupported()) { options.add(ExtendedSocketOptions.SO_FLOW_SLA); } + if (getSocket() != null && isQuickAckAvailable()) { + options.add(ExtendedSocketOptions.SO_QUICKACK); + } return options; } --- old/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c 2016-02-24 13:34:29.932280937 +0530 +++ new/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c 2016-02-24 13:34:29.812280935 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,7 @@ /* OS specific code is implemented in these three functions */ static jboolean flowSupported0() ; +static jboolean quickack_available(); /* * Class: sun_net_ExtendedOptionsImpl @@ -142,6 +143,25 @@ } /* + * Returns a java.lang.Boolean based on 'b' + */ +static jobject createBoolean(JNIEnv *env, int b) { + static jclass b_class; + static jmethodID b_ctrID; + + if (b_class == NULL) { + jclass c = (*env)->FindClass(env, "java/lang/Boolean"); + CHECK_NULL_RETURN(c, NULL); + b_ctrID = (*env)->GetMethodID(env, c, "", "(Z)V"); + CHECK_NULL_RETURN(b_ctrID, NULL); + b_class = (*env)->NewGlobalRef(env, c); + CHECK_NULL_RETURN(b_class, NULL); + } + + return ((*env)->NewObject(env, b_class, b_ctrID, (jboolean) (b != 0))); +} + +/* * Retrieve the int file-descriptor from a public socket type object. * Gets impl, then the FileDescriptor from the impl, and then the fd * from that. @@ -337,8 +357,120 @@ #endif /* __solaris__ */ +#ifdef __linux__ + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: setQuickAckOption + * Signature: (Ljava/io/FileDescriptor;Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption +(JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) { + int fd = getFD(env, fileDesc); + int optval; + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + } else { + int rv; + optval = (on ? 1 : 0); + rv = setsockopt(fd, SOL_SOCKET, SO_QUICKACK, &optval, sizeof (optval)); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "set option SO_REUSEPORT failed"); + } + } + } +} + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: getQuickAckOption + * Signature: (Ljava/io/FileDescriptor;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) +{ + int fd = getFD(env, fileDesc); + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + return JNI_FALSE; + } else { + int on; + socklen_t sz = sizeof(on); + int rv = getsockopt(fd, SOL_SOCKET, SO_QUICKACK, &on, &sz); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "setoption SO_QUICKACK failed"); + } + } + return createBoolean(env, on); + } +} + +static jboolean isQuickAckAvailable; +static jboolean isQuickAckAvailableChecked = JNI_FALSE; +static jboolean quickack_available() { + int one = 1; + int rv, s; + if (isQuickAckAvailableChecked) { + return isQuickAckAvailable; + } + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + isQuickAckAvailable = JNI_FALSE; + isQuickAckAvailableChecked = JNI_TRUE; + return JNI_FALSE; + } + rv = setsockopt(s, SOL_SOCKET, SO_QUICKACK, (void *) &one, sizeof (one)); + isQuickAckAvailableChecked = JNI_TRUE; + if (rv != 0 && errno == ENOPROTOOPT) { + isQuickAckAvailable = JNI_FALSE; + } else { + isQuickAckAvailable = JNI_TRUE; + } + close(s); + return isQuickAckAvailable; +} + +#else + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + return JNI_FALSE; +} + +static jboolean quickack_available() { + return JNI_FALSE; +} + +#endif /* __linux__ */ + JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported (JNIEnv *env, jclass UNUSED) { return flowSupported0(); } + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_isQuickAckAvailable0 + (JNIEnv *env, jclass UNUSED) +{ + return quickack_available(); +} --- old/src/java.base/unix/native/libnet/net_util_md.h 2016-02-24 13:34:30.296280942 +0530 +++ new/src/java.base/unix/native/libnet/net_util_md.h 2016-02-24 13:34:30.164280940 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,6 +100,7 @@ #ifdef __linux__ int kernelIsV24(); +#define SO_QUICKACK 0x0C #ifdef AF_INET6 int getDefaultIPv6Interface(struct in6_addr *target_addr); #endif --- old/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c 2016-02-24 13:34:30.644280947 +0530 +++ new/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c 2016-02-24 13:34:30.528280946 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,4 +62,25 @@ (JNIEnv *env, jclass UNUSED) { return JNI_FALSE; +} + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + return JNI_FALSE; +} + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_isQuickAckAvailable0 + (JNIEnv *env, jclass UNUSED) +{ + return JNI_FALSE; } --- old/test/java/net/SocketOption/OptionsTest.java 2016-02-24 13:34:31.008280953 +0530 +++ new/test/java/net/SocketOption/OptionsTest.java 2016-02-24 13:34:30.884280951 +0530 @@ -53,6 +53,7 @@ Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE), Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)), Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), + Test.create(jdk.net.ExtendedSocketOptions.SO_QUICKACK, Boolean.FALSE), Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)), Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) @@ -61,6 +62,7 @@ static Test[] serverSocketTests = new Test[] { Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), + Test.create(jdk.net.ExtendedSocketOptions.SO_QUICKACK, Boolean.FALSE), Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) }; @@ -97,15 +99,19 @@ Socket c = new Socket("127.0.0.1", srv.getLocalPort()); Socket s = srv.accept(); ) { + Set> options = c.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); for (int i=0; i> options = c.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); for (int i=0; i> options = socket.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) { return Boolean.valueOf(socket.getKeepAlive()); } else if (option.equals(StandardSocketOptions.SO_SNDBUF)) { @@ -183,7 +194,9 @@ return Integer.valueOf(socket.getReceiveBufferSize()); } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { return Boolean.valueOf(socket.getReuseAddress()); - } else if (option.equals(StandardSocketOptions.SO_LINGER)) { + } else if (option.equals(jdk.net.ExtendedSocketOptions.SO_QUICKACK) && quickAck) { + return socket.getOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + } else if (option.equals(StandardSocketOptions.SO_LINGER)) { return Integer.valueOf(socket.getSoLinger()); } else if (option.equals(StandardSocketOptions.IP_TOS)) { return Integer.valueOf(socket.getTrafficClass()); @@ -194,11 +207,16 @@ } } else if (type.equals(ServerSocket.class)) { ServerSocket socket = (ServerSocket)s; + Set> options = socket.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + if (option.equals(StandardSocketOptions.SO_RCVBUF)) { return Integer.valueOf(socket.getReceiveBufferSize()); } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { return Boolean.valueOf(socket.getReuseAddress()); - } else if (option.equals(StandardSocketOptions.IP_TOS)) { + }else if (option.equals(jdk.net.ExtendedSocketOptions.SO_QUICKACK) && quickAck) { + return socket.getOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + } else if (option.equals(StandardSocketOptions.IP_TOS)) { return Integer.valueOf(jdk.net.Sockets.getOption( socket, StandardSocketOptions.IP_TOS)); } else { @@ -206,7 +224,6 @@ } } else if (type.equals(DatagramSocket.class)) { DatagramSocket socket = (DatagramSocket)s; - if (option.equals(StandardSocketOptions.SO_SNDBUF)) { return Integer.valueOf(socket.getSendBufferSize()); } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { @@ -221,7 +238,6 @@ } else if (type.equals(MulticastSocket.class)) { MulticastSocket socket = (MulticastSocket)s; - if (option.equals(StandardSocketOptions.SO_SNDBUF)) { return Integer.valueOf(socket.getSendBufferSize()); } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { --- old/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java 2016-02-24 13:34:31.360280958 +0530 +++ new/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java 2016-02-24 13:34:31.232280956 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,11 +141,13 @@ try { // check supported options Set> options = ch.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); if (!options.contains(SO_REUSEADDR)) throw new RuntimeException("SO_REUSEADDR should be supported"); if (!options.contains(SO_RCVBUF)) throw new RuntimeException("SO_RCVBUF should be supported"); - + if (!options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK) && quickAck) + throw new RuntimeException("SO_QUICKACK should be supported"); // allowed to change when not bound ch.setOption(SO_RCVBUF, 256*1024); // can't check int before = ch.getOption(SO_RCVBUF); @@ -156,6 +158,12 @@ checkOption(ch, SO_REUSEADDR, true); ch.setOption(SO_REUSEADDR, false); checkOption(ch, SO_REUSEADDR, false); + if (quickAck) { + ch.setOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK, true); + checkOption(ch, jdk.net.ExtendedSocketOptions.SO_QUICKACK, true); + ch.setOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK, false); + checkOption(ch, jdk.net.ExtendedSocketOptions.SO_QUICKACK, false); + } } finally { ch.close(); } --- old/test/java/nio/channels/AsynchronousSocketChannel/Basic.java 2016-02-24 13:34:31.712280963 +0530 +++ new/test/java/nio/channels/AsynchronousSocketChannel/Basic.java 2016-02-24 13:34:31.584280961 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ import java.util.concurrent.atomic.*; import java.io.Closeable; import java.io.IOException; +import java.util.Set; public class Basic { static final Random rand = new Random(); @@ -165,6 +166,19 @@ // read others (can't check as actual value is implementation dependent) ch.getOption(SO_RCVBUF); ch.getOption(SO_SNDBUF); + + Set> options = ch.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + if (quickAck) { + if (ch.getOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK)) { + throw new RuntimeException("Default of SO_QUICKACK should be 'false'"); + } + + if (!ch.setOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK, true). + getOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK)) { + throw new RuntimeException("SO_QUICKACK did not change"); + } + } } } --- old/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java 2016-02-24 13:34:32.076280969 +0530 +++ new/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java 2016-02-24 13:34:31.948280967 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,9 @@ // check supported options Set> options = ssc.supportedOptions(); + boolean quickAck = options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK); + if (!options.contains(jdk.net.ExtendedSocketOptions.SO_QUICKACK) && quickAck) + throw new RuntimeException("SO_REUSEPORT should be supported"); if (!options.contains(SO_REUSEADDR)) throw new RuntimeException("SO_REUSEADDR should be supported"); if (!options.contains(SO_RCVBUF)) @@ -65,6 +68,13 @@ ssc.setOption(SO_REUSEADDR, false); checkOption(ssc, SO_REUSEADDR, false); + if (quickAck) { + ssc.setOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK, true); + checkOption(ssc, jdk.net.ExtendedSocketOptions.SO_QUICKACK, true); + ssc.setOption(jdk.net.ExtendedSocketOptions.SO_QUICKACK, false); + checkOption(ssc, jdk.net.ExtendedSocketOptions.SO_QUICKACK, false); + } + // NullPointerException try { ssc.setOption(null, "value");