jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java
changeset 18192 fa6bd0992104
parent 16866 e659009ee08d
child 18201 f0c28a4c1ab2
--- a/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Thu Mar 14 14:45:55 2013 +0100
+++ b/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Thu Mar 14 13:46:15 2013 -0700
@@ -42,10 +42,20 @@
 {
     static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
 
-    public DualStackPlainSocketImpl() {}
+
+    // true if this socket is exclusively bound
+    private final boolean exclusiveBind;
+
+    // emulates SO_REUSEADDR when exclusiveBind is true
+    private boolean isReuseAddress;
 
-    public DualStackPlainSocketImpl(FileDescriptor fd) {
+    public DualStackPlainSocketImpl(boolean exclBind) {
+        exclusiveBind = exclBind;
+    }
+
+    public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
         this.fd = fd;
+        exclusiveBind = exclBind;
     }
 
     void socketCreate(boolean stream) throws IOException {
@@ -93,7 +103,7 @@
         if (address == null)
             throw new NullPointerException("inet address argument is null.");
 
-        bind0(nativefd, address, port);
+        bind0(nativefd, address, port, exclusiveBind);
         if (port == 0) {
             localport = localPort0(nativefd);
         } else {
@@ -162,6 +172,8 @@
         shutdown0(nativefd, howto);
     }
 
+    // Intentional fallthrough after SO_REUSEADDR
+    @SuppressWarnings("fallthrough")
     void socketSetOption(int opt, boolean on, Object value)
         throws SocketException {
         int nativefd = checkAndReturnNativeFD();
@@ -175,8 +187,13 @@
         switch(opt) {
             case TCP_NODELAY :
             case SO_OOBINLINE :
+            case SO_REUSEADDR :
+                if (exclusiveBind) {
+                    // SO_REUSEADDR emulated when using exclusive bind
+                    isReuseAddress = on;
+                    return;
+                }
             case SO_KEEPALIVE :
-            case SO_REUSEADDR :
                 optionValue = on ? 1 : 0;
                 break;
             case SO_SNDBUF :
@@ -207,6 +224,10 @@
             return 0;  // return value doesn't matter.
         }
 
+        // SO_REUSEADDR emulated when using exclusive bind
+        if (opt == SO_REUSEADDR && exclusiveBind)
+            return isReuseAddress? 1 : -1;
+
         int value = getIntOption(nativefd, opt);
 
         switch (opt) {
@@ -243,7 +264,8 @@
 
     static native int socket0(boolean stream, boolean v6Only) throws IOException;
 
-    static native void bind0(int fd, InetAddress localAddress, int localport)
+    static native void bind0(int fd, InetAddress localAddress, int localport,
+                             boolean exclBind)
         throws IOException;
 
     static native int connect0(int fd, InetAddress remote, int remotePort)