mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8212132: (dc) Remove DatagramChannelImpl finalize method
Reviewed-by: bpb, chegar, dfuchs, martin
This commit is contained in:
parent
a2844b54e1
commit
0290476112
3 changed files with 219 additions and 58 deletions
|
@ -27,6 +27,8 @@ package sun.nio.ch;
|
|||
|
||||
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.Objects;
|
|||
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 @@ class DatagramChannelImpl
|
|||
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 @@ class DatagramChannelImpl
|
|||
// 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 @@ class DatagramChannelImpl
|
|||
ResourceManager.afterUdpClose();
|
||||
throw ioe;
|
||||
}
|
||||
this.cleaner = CleanerFactory.cleaner().register(this, closerFor(fd));
|
||||
}
|
||||
|
||||
public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family)
|
||||
|
@ -164,6 +169,7 @@ class DatagramChannelImpl
|
|||
ResourceManager.afterUdpClose();
|
||||
throw ioe;
|
||||
}
|
||||
this.cleaner = CleanerFactory.cleaner().register(this, closerFor(fd));
|
||||
}
|
||||
|
||||
public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
|
||||
|
@ -179,6 +185,7 @@ class DatagramChannelImpl
|
|||
: 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 @@ class DatagramChannelImpl
|
|||
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 @@ class DatagramChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
@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 @@ class DatagramChannelImpl
|
|||
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 --
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ProtocolFamily;
|
||||
|
@ -106,7 +105,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
|
|||
|
||||
// set by SocketImpl.create, protected by stateLock
|
||||
private boolean stream;
|
||||
private FileDescriptorCloser closer;
|
||||
private Cleanable cleaner;
|
||||
|
||||
// set to true when the socket is in non-blocking mode
|
||||
private volatile boolean nonBlocking;
|
||||
|
@ -471,9 +470,10 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
|
|||
ResourceManager.afterUdpClose();
|
||||
throw ioe;
|
||||
}
|
||||
Runnable closer = closerFor(fd, stream);
|
||||
this.fd = fd;
|
||||
this.stream = stream;
|
||||
this.closer = FileDescriptorCloser.create(this);
|
||||
this.cleaner = CleanerFactory.cleaner().register(this, closer);
|
||||
this.state = ST_UNCONNECTED;
|
||||
}
|
||||
}
|
||||
|
@ -777,10 +777,11 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
|
|||
}
|
||||
|
||||
// set the fields
|
||||
Runnable closer = closerFor(newfd, true);
|
||||
synchronized (nsi.stateLock) {
|
||||
nsi.fd = newfd;
|
||||
nsi.stream = true;
|
||||
nsi.closer = FileDescriptorCloser.create(nsi);
|
||||
nsi.cleaner = CleanerFactory.cleaner().register(nsi, closer);
|
||||
nsi.localport = localAddress.getPort();
|
||||
nsi.address = isaa[0].getAddress();
|
||||
nsi.port = isaa[0].getPort();
|
||||
|
@ -850,7 +851,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
|
|||
assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
|
||||
if (readerThread == 0 && writerThread == 0) {
|
||||
try {
|
||||
closer.run();
|
||||
cleaner.clean();
|
||||
} catch (UncheckedIOException ioe) {
|
||||
throw ioe.getCause();
|
||||
} finally {
|
||||
|
@ -1193,53 +1194,28 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
|
|||
}
|
||||
|
||||
/**
|
||||
* A task that closes a SocketImpl's file descriptor. The task runs when the
|
||||
* SocketImpl is explicitly closed and when the SocketImpl becomes phantom
|
||||
* reachable.
|
||||
* Returns an action to close the given file descriptor.
|
||||
*/
|
||||
private static class FileDescriptorCloser implements Runnable {
|
||||
private static final VarHandle CLOSED;
|
||||
static {
|
||||
try {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
CLOSED = l.findVarHandle(FileDescriptorCloser.class,
|
||||
"closed",
|
||||
boolean.class);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private final FileDescriptor fd;
|
||||
private final boolean stream;
|
||||
private volatile boolean closed;
|
||||
|
||||
FileDescriptorCloser(FileDescriptor fd, boolean stream) {
|
||||
this.fd = fd;
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
static FileDescriptorCloser create(NioSocketImpl impl) {
|
||||
assert Thread.holdsLock(impl.stateLock);
|
||||
var closer = new FileDescriptorCloser(impl.fd, impl.stream);
|
||||
CleanerFactory.cleaner().register(impl, closer);
|
||||
return closer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (CLOSED.compareAndSet(this, false, true)) {
|
||||
private static Runnable closerFor(FileDescriptor fd, boolean stream) {
|
||||
if (stream) {
|
||||
return () -> {
|
||||
try {
|
||||
nd.close(fd);
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return () -> {
|
||||
try {
|
||||
nd.close(fd);
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
} finally {
|
||||
if (!stream) {
|
||||
// decrement
|
||||
ResourceManager.afterUdpClose();
|
||||
}
|
||||
// decrement
|
||||
ResourceManager.afterUdpClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue