changeset 57701:d78e03ecb55f

8233002: Further enhance datagram socket support Reviewed-by: alanb, chegar, dfuchs
author igerasim
date Tue, 29 Oct 2019 09:51:37 -0700
parents 14e425e3a23c
children dee9bb1fcc49
files src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java src/java.base/share/classes/java/net/SocketCleanable.java src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java
diffstat 4 files changed, 36 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Mon Oct 28 18:53:51 2019 -0700
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Tue Oct 29 09:51:37 2019 -0700
@@ -97,7 +97,7 @@
         fd = new FileDescriptor();
         try {
             datagramSocketCreate();
-            SocketCleanable.register(fd);
+            SocketCleanable.register(fd, false);
         } catch (SocketException ioe) {
             ResourceManager.afterUdpClose();
             fd = null;
--- a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Mon Oct 28 18:53:51 2019 -0700
+++ b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Tue Oct 29 09:51:37 2019 -0700
@@ -127,7 +127,7 @@
             fd = new FileDescriptor();
             try {
                 socketCreate(false);
-                SocketCleanable.register(fd);
+                SocketCleanable.register(fd, false);
             } catch (IOException ioe) {
                 ResourceManager.afterUdpClose();
                 fd = null;
@@ -136,7 +136,7 @@
         } else {
             fd = new FileDescriptor();
             socketCreate(true);
-            SocketCleanable.register(fd);
+            SocketCleanable.register(fd, true);
         }
     }
 
@@ -580,7 +580,7 @@
         } finally {
             releaseFD();
         }
-        SocketCleanable.register(si.fd);
+        SocketCleanable.register(si.fd, true);
     }
 
     /**
@@ -683,9 +683,6 @@
     protected void close() throws IOException {
         synchronized(fdLock) {
             if (fd != null) {
-                if (!stream) {
-                    ResourceManager.afterUdpClose();
-                }
                 if (fdUseCount == 0) {
                     if (closePending) {
                         return;
@@ -840,7 +837,13 @@
      */
     protected void socketClose() throws IOException {
         SocketCleanable.unregister(fd);
-        socketClose0(false);
+        try {
+            socketClose0(false);
+        } finally {
+            if (!stream) {
+                ResourceManager.afterUdpClose();
+            }
+        }
     }
 
     abstract void socketCreate(boolean stream) throws IOException;
--- a/src/java.base/share/classes/java/net/SocketCleanable.java	Mon Oct 28 18:53:51 2019 -0700
+++ b/src/java.base/share/classes/java/net/SocketCleanable.java	Tue Oct 29 09:51:37 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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,7 @@
 import java.io.UncheckedIOException;
 import java.lang.ref.Cleaner;
 
+import sun.net.ResourceManager;
 
 /**
  * Cleanable for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
@@ -56,17 +57,22 @@
     // The raw fd to close
     private final int fd;
 
+    // true for socket, false for datagram socket
+    private final boolean stream;
+
     /**
      * Register a socket specific Cleanable with the FileDescriptor
      * if the FileDescriptor is non-null and the raw fd is != -1.
      *
-     * @param fdo the FileDescriptor; may be null
+     * @param fdo     the FileDescriptor; may be null
+     * @param stream  false for datagram socket
      */
-    static void register(FileDescriptor fdo) {
+    static void register(FileDescriptor fdo, boolean stream) {
         if (fdo != null && fdo.valid()) {
             int fd = fdAccess.get(fdo);
             fdAccess.registerCleanup(fdo,
-                    new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
+                    new SocketCleanable(fdo, CleanerFactory.cleaner(),
+                                        fd, stream));
         }
     }
 
@@ -86,10 +92,13 @@
      * @param obj     the object to monitor
      * @param cleaner the cleaner
      * @param fd      file descriptor to close
+     * @param stream  false for datagram socket
      */
-    private SocketCleanable(FileDescriptor obj, Cleaner cleaner, int fd) {
+    private SocketCleanable(FileDescriptor obj, Cleaner cleaner,
+                            int fd, boolean stream) {
         super(obj, cleaner);
         this.fd = fd;
+        this.stream = stream;
     }
 
     /**
@@ -101,6 +110,10 @@
             cleanupClose0(fd);
         } catch (IOException ioe) {
             throw new UncheckedIOException("close", ioe);
+        } finally {
+            if (!stream) {
+                ResourceManager.afterUdpClose();
+            }
         }
     }
 }
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Mon Oct 28 18:53:51 2019 -0700
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Tue Oct 29 09:51:37 2019 -0700
@@ -87,7 +87,9 @@
         fd1 = new FileDescriptor();
         try {
             super.create();
-            SocketCleanable.register(fd1);
+            // make SocketCleanable treat fd1 as a stream socket
+            // to avoid touching the counter in ResourceManager
+            SocketCleanable.register(fd1, true);
         } catch (SocketException e) {
             fd1 = null;
             throw e;
@@ -114,8 +116,10 @@
 
         bind0(lport, laddr, exclusiveBind);
 
-        SocketCleanable.register(fd);
-        SocketCleanable.register(fd1);
+        SocketCleanable.register(fd, false);
+        // make SocketCleanable treat fd1 as a stream socket
+        // to avoid touching the counter in ResourceManager
+        SocketCleanable.register(fd1, true);
     }
 
     protected synchronized void receive(DatagramPacket p)