8233002: Further enhance datagram socket support

Reviewed-by: alanb, chegar, dfuchs
This commit is contained in:
Ivan Gerasimov 2019-10-29 09:51:37 -07:00
parent c5f884c6d1
commit 34e36a8c01
4 changed files with 36 additions and 16 deletions

View File

@ -97,7 +97,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
fd = new FileDescriptor();
try {
datagramSocketCreate();
SocketCleanable.register(fd);
SocketCleanable.register(fd, false);
} catch (SocketException ioe) {
ResourceManager.afterUdpClose();
fd = null;

View File

@ -127,7 +127,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
fd = new FileDescriptor();
try {
socketCreate(false);
SocketCleanable.register(fd);
SocketCleanable.register(fd, false);
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
fd = null;
@ -136,7 +136,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
} else {
fd = new FileDescriptor();
socketCreate(true);
SocketCleanable.register(fd);
SocketCleanable.register(fd, true);
}
}
@ -580,7 +580,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
} finally {
releaseFD();
}
SocketCleanable.register(si.fd);
SocketCleanable.register(si.fd, true);
}
/**
@ -683,9 +683,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
protected void close() throws IOException {
synchronized(fdLock) {
if (fd != null) {
if (!stream) {
ResourceManager.afterUdpClose();
}
if (fdUseCount == 0) {
if (closePending) {
return;
@ -840,7 +837,13 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
*/
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;

View File

@ -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.IOException;
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 @@ final class SocketCleanable extends PhantomCleanable<FileDescriptor> {
// 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 @@ final class SocketCleanable extends PhantomCleanable<FileDescriptor> {
* @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 @@ final class SocketCleanable extends PhantomCleanable<FileDescriptor> {
cleanupClose0(fd);
} catch (IOException ioe) {
throw new UncheckedIOException("close", ioe);
} finally {
if (!stream) {
ResourceManager.afterUdpClose();
}
}
}
}

View File

@ -87,7 +87,9 @@ final class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocket
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 @@ final class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocket
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)