diff -r d3382812b788 -r 9261ad32cba9 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Oct 25 13:17:31 2019 -0700 +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Sun Oct 27 12:13:51 2019 +0000 @@ -27,6 +27,8 @@ import java.io.FileDescriptor; import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.ref.Cleaner.Cleanable; import java.net.DatagramSocket; import java.net.Inet4Address; import java.net.Inet6Address; @@ -55,6 +57,7 @@ import java.util.Set; import java.util.concurrent.locks.ReentrantLock; +import jdk.internal.ref.CleanerFactory; import sun.net.ResourceManager; import sun.net.ext.ExtendedSocketOptions; import sun.net.util.IPAddressUtil; @@ -68,7 +71,7 @@ implements SelChImpl { // Used to make native read and write calls - private static NativeDispatcher nd = new DatagramDispatcher(); + private static final NativeDispatcher nd = new DatagramDispatcher(); // The protocol family of the socket private final ProtocolFamily family; @@ -76,6 +79,7 @@ // Our file descriptor private final FileDescriptor fd; private final int fdVal; + private final Cleanable cleaner; // Cached InetAddress and port for unconnected DatagramChannels // used by receive0 @@ -138,6 +142,7 @@ ResourceManager.afterUdpClose(); throw ioe; } + this.cleaner = CleanerFactory.cleaner().register(this, closerFor(fd)); } public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) @@ -164,6 +169,7 @@ ResourceManager.afterUdpClose(); throw ioe; } + this.cleaner = CleanerFactory.cleaner().register(this, closerFor(fd)); } public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd) @@ -179,6 +185,7 @@ : StandardProtocolFamily.INET; this.fd = fd; this.fdVal = IOUtil.fdVal(fd); + this.cleaner = CleanerFactory.cleaner().register(this, closerFor(fd)); synchronized (stateLock) { this.localAddress = Net.localAddress(fd); } @@ -1181,10 +1188,10 @@ if ((readerThread == 0) && (writerThread == 0) && !isRegistered()) { state = ST_CLOSED; try { - nd.close(fd); - } finally { - // notify resource manager - ResourceManager.afterUdpClose(); + // close socket + cleaner.clean(); + } catch (UncheckedIOException ioe) { + throw ioe.getCause(); } return true; } else { @@ -1283,13 +1290,6 @@ } } - @SuppressWarnings("deprecation") - protected void finalize() throws IOException { - // fd is null if constructor threw exception - if (fd != null) - close(); - } - /** * Translates native poll revent set into a ready operation set */ @@ -1377,6 +1377,21 @@ return fdVal; } + /** + * Returns an action to close the given file descriptor. + */ + private static Runnable closerFor(FileDescriptor fd) { + return () -> { + try { + nd.close(fd); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } finally { + // decrement + ResourceManager.afterUdpClose(); + } + }; + } // -- Native methods --