--- 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 --