mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8299976: Initialize static fields in Net eagerly
Reviewed-by: alanb
This commit is contained in:
parent
3ffc955783
commit
ce1193a1ed
1 changed files with 83 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2023, 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
|
||||
|
@ -48,6 +48,7 @@ import java.nio.channels.UnsupportedAddressTypeException;
|
|||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
|
@ -65,45 +66,35 @@ public class Net {
|
|||
};
|
||||
|
||||
// set to true if exclusive binding is on for Windows
|
||||
private static final boolean exclusiveBind;
|
||||
private static final boolean EXCLUSIVE_BIND;
|
||||
|
||||
// set to true if the fast tcp loopback should be enabled on Windows
|
||||
private static final boolean fastLoopback;
|
||||
private static final boolean FAST_LOOPBACK;
|
||||
|
||||
// -- Miscellaneous utilities --
|
||||
|
||||
private static volatile boolean checkedIPv6;
|
||||
private static volatile boolean isIPv6Available;
|
||||
private static volatile boolean checkedReusePort;
|
||||
private static volatile boolean isReusePortAvailable;
|
||||
private static final boolean IPV6_AVAILABLE;
|
||||
private static final boolean SO_REUSEPORT_AVAILABLE;
|
||||
|
||||
/**
|
||||
* Tells whether dual-IPv4/IPv6 sockets should be used.
|
||||
*/
|
||||
static boolean isIPv6Available() {
|
||||
if (!checkedIPv6) {
|
||||
isIPv6Available = isIPv6Available0();
|
||||
checkedIPv6 = true;
|
||||
}
|
||||
return isIPv6Available;
|
||||
return IPV6_AVAILABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether SO_REUSEPORT is supported.
|
||||
*/
|
||||
static boolean isReusePortAvailable() {
|
||||
if (!checkedReusePort) {
|
||||
isReusePortAvailable = isReusePortAvailable0();
|
||||
checkedReusePort = true;
|
||||
}
|
||||
return isReusePortAvailable;
|
||||
return SO_REUSEPORT_AVAILABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if exclusive binding is on
|
||||
*/
|
||||
static boolean useExclusiveBind() {
|
||||
return exclusiveBind;
|
||||
return EXCLUSIVE_BIND;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,16 +131,14 @@ public class Net {
|
|||
}
|
||||
|
||||
public static InetSocketAddress checkAddress(SocketAddress sa) {
|
||||
if (sa == null)
|
||||
throw new NullPointerException();
|
||||
if (!(sa instanceof InetSocketAddress))
|
||||
Objects.requireNonNull(sa);
|
||||
if (!(sa instanceof InetSocketAddress isa))
|
||||
throw new UnsupportedAddressTypeException(); // ## needs arg
|
||||
InetSocketAddress isa = (InetSocketAddress)sa;
|
||||
if (isa.isUnresolved())
|
||||
throw new UnresolvedAddressException(); // ## needs arg
|
||||
InetAddress addr = isa.getAddress();
|
||||
if (!(addr instanceof Inet4Address || addr instanceof Inet6Address))
|
||||
throw new IllegalArgumentException("Invalid address type");
|
||||
throw new IllegalArgumentException("Invalid address type: " + addr.getClass().getName());
|
||||
return isa;
|
||||
}
|
||||
|
||||
|
@ -164,49 +153,53 @@ public class Net {
|
|||
}
|
||||
|
||||
static InetSocketAddress asInetSocketAddress(SocketAddress sa) {
|
||||
if (!(sa instanceof InetSocketAddress))
|
||||
if (!(sa instanceof InetSocketAddress isa))
|
||||
throw new UnsupportedAddressTypeException();
|
||||
return (InetSocketAddress)sa;
|
||||
return isa;
|
||||
}
|
||||
|
||||
static void translateToSocketException(Exception x)
|
||||
throws SocketException
|
||||
{
|
||||
if (x instanceof SocketException)
|
||||
throw (SocketException)x;
|
||||
if (x instanceof SocketException se)
|
||||
throw se;
|
||||
Exception nx = x;
|
||||
if (x instanceof ClosedChannelException)
|
||||
nx = new SocketException("Socket is closed");
|
||||
nx = newSocketException("Socket is closed");
|
||||
else if (x instanceof NotYetConnectedException)
|
||||
nx = new SocketException("Socket is not connected");
|
||||
nx = newSocketException("Socket is not connected");
|
||||
else if (x instanceof AlreadyBoundException)
|
||||
nx = new SocketException("Already bound");
|
||||
nx = newSocketException("Already bound");
|
||||
else if (x instanceof NotYetBoundException)
|
||||
nx = new SocketException("Socket is not bound yet");
|
||||
nx = newSocketException("Socket is not bound yet");
|
||||
else if (x instanceof UnsupportedAddressTypeException)
|
||||
nx = new SocketException("Unsupported address type");
|
||||
nx = newSocketException("Unsupported address type");
|
||||
else if (x instanceof UnresolvedAddressException)
|
||||
nx = new SocketException("Unresolved address");
|
||||
nx = newSocketException("Unresolved address");
|
||||
else if (x instanceof IOException) {
|
||||
nx = new SocketException(x.getMessage());
|
||||
nx = newSocketException(x.getMessage());
|
||||
}
|
||||
if (nx != x)
|
||||
nx.initCause(x);
|
||||
|
||||
if (nx instanceof SocketException)
|
||||
throw (SocketException)nx;
|
||||
else if (nx instanceof RuntimeException)
|
||||
throw (RuntimeException)nx;
|
||||
if (nx instanceof SocketException se)
|
||||
throw se;
|
||||
else if (nx instanceof RuntimeException re)
|
||||
throw re;
|
||||
else
|
||||
throw new Error("Untranslated exception", nx);
|
||||
}
|
||||
|
||||
private static SocketException newSocketException(String msg) {
|
||||
return new SocketException(msg);
|
||||
}
|
||||
|
||||
static void translateException(Exception x,
|
||||
boolean unknownHostForUnresolved)
|
||||
throws IOException
|
||||
{
|
||||
if (x instanceof IOException)
|
||||
throw (IOException)x;
|
||||
if (x instanceof IOException ioe)
|
||||
throw ioe;
|
||||
// Throw UnknownHostException from here since it cannot
|
||||
// be thrown as a SocketException
|
||||
if (unknownHostForUnresolved &&
|
||||
|
@ -255,40 +248,40 @@ public class Net {
|
|||
return new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
|
||||
}
|
||||
|
||||
private static final InetAddress anyLocalInet4Address;
|
||||
private static final InetAddress anyLocalInet6Address;
|
||||
private static final InetAddress inet4LoopbackAddress;
|
||||
private static final InetAddress inet6LoopbackAddress;
|
||||
private static final InetAddress ANY_LOCAL_INET4ADDRESS;
|
||||
private static final InetAddress ANY_LOCAL_INET6ADDRESS;
|
||||
private static final InetAddress INET4_LOOPBACK_ADDRESS;
|
||||
private static final InetAddress INET6_LOOPBACK_ADDRESS;
|
||||
static {
|
||||
try {
|
||||
anyLocalInet4Address = inet4FromInt(0);
|
||||
assert anyLocalInet4Address instanceof Inet4Address
|
||||
&& anyLocalInet4Address.isAnyLocalAddress();
|
||||
ANY_LOCAL_INET4ADDRESS = inet4FromInt(0);
|
||||
assert ANY_LOCAL_INET4ADDRESS instanceof Inet4Address
|
||||
&& ANY_LOCAL_INET4ADDRESS.isAnyLocalAddress();
|
||||
|
||||
anyLocalInet6Address = InetAddress.getByAddress(new byte[16]);
|
||||
assert anyLocalInet6Address instanceof Inet6Address
|
||||
&& anyLocalInet6Address.isAnyLocalAddress();
|
||||
ANY_LOCAL_INET6ADDRESS = InetAddress.getByAddress(new byte[16]);
|
||||
assert ANY_LOCAL_INET6ADDRESS instanceof Inet6Address
|
||||
&& ANY_LOCAL_INET6ADDRESS.isAnyLocalAddress();
|
||||
|
||||
inet4LoopbackAddress = inet4FromInt(0x7f000001);
|
||||
assert inet4LoopbackAddress instanceof Inet4Address
|
||||
&& inet4LoopbackAddress.isLoopbackAddress();
|
||||
INET4_LOOPBACK_ADDRESS = inet4FromInt(0x7f000001);
|
||||
assert INET4_LOOPBACK_ADDRESS instanceof Inet4Address
|
||||
&& INET4_LOOPBACK_ADDRESS.isLoopbackAddress();
|
||||
|
||||
byte[] bytes = new byte[16];
|
||||
bytes[15] = 0x01;
|
||||
inet6LoopbackAddress = InetAddress.getByAddress(bytes);
|
||||
assert inet6LoopbackAddress instanceof Inet6Address
|
||||
&& inet6LoopbackAddress.isLoopbackAddress();
|
||||
INET6_LOOPBACK_ADDRESS = InetAddress.getByAddress(bytes);
|
||||
assert INET6_LOOPBACK_ADDRESS instanceof Inet6Address
|
||||
&& INET6_LOOPBACK_ADDRESS.isLoopbackAddress();
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
static InetAddress inet4LoopbackAddress() {
|
||||
return inet4LoopbackAddress;
|
||||
return INET4_LOOPBACK_ADDRESS;
|
||||
}
|
||||
|
||||
static InetAddress inet6LoopbackAddress() {
|
||||
return inet6LoopbackAddress;
|
||||
return INET6_LOOPBACK_ADDRESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,9 +291,9 @@ public class Net {
|
|||
*/
|
||||
static InetAddress anyLocalAddress(ProtocolFamily family) {
|
||||
if (family == StandardProtocolFamily.INET) {
|
||||
return anyLocalInet4Address;
|
||||
return ANY_LOCAL_INET4ADDRESS;
|
||||
} else if (family == StandardProtocolFamily.INET6) {
|
||||
return anyLocalInet6Address;
|
||||
return ANY_LOCAL_INET6ADDRESS;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -317,8 +310,8 @@ public class Net {
|
|||
Enumeration<InetAddress> addrs = interf.getInetAddresses();
|
||||
while (addrs.hasMoreElements()) {
|
||||
InetAddress addr = addrs.nextElement();
|
||||
if (addr instanceof Inet4Address) {
|
||||
return (Inet4Address)addr;
|
||||
if (addr instanceof Inet4Address inet4Address) {
|
||||
return inet4Address;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -338,7 +331,7 @@ public class Net {
|
|||
address |= ((addr[0] << 24) & 0xFF000000);
|
||||
return address;
|
||||
}
|
||||
throw new AssertionError("Should not reach here");
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,7 +347,7 @@ public class Net {
|
|||
try {
|
||||
return InetAddress.getByAddress(addr);
|
||||
} catch (UnknownHostException uhe) {
|
||||
throw new AssertionError("Should not reach here");
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,12 +372,12 @@ public class Net {
|
|||
return address;
|
||||
}
|
||||
|
||||
throw new AssertionError("Should not reach here");
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
|
||||
// -- Socket options
|
||||
|
||||
static final ExtendedSocketOptions extendedOptions =
|
||||
static final ExtendedSocketOptions EXTENDED_OPTIONS =
|
||||
ExtendedSocketOptions.getInstance();
|
||||
|
||||
static void setSocketOption(FileDescriptor fd, SocketOption<?> name, Object value)
|
||||
|
@ -404,13 +397,13 @@ public class Net {
|
|||
Class<?> type = name.type();
|
||||
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
|
||||
|
||||
if (extendedOptions.isOptionSupported(name)) {
|
||||
extendedOptions.setOption(fd, name, value, isIPv6);
|
||||
if (EXTENDED_OPTIONS.isOptionSupported(name)) {
|
||||
EXTENDED_OPTIONS.setOption(fd, name, value, isIPv6);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != Integer.class && type != Boolean.class)
|
||||
throw new AssertionError("Should not reach here");
|
||||
throw shouldNotReachHere();
|
||||
|
||||
// special handling
|
||||
if (name == StandardSocketOptions.SO_RCVBUF ||
|
||||
|
@ -466,14 +459,14 @@ public class Net {
|
|||
{
|
||||
Class<?> type = name.type();
|
||||
|
||||
if (extendedOptions.isOptionSupported(name)) {
|
||||
if (EXTENDED_OPTIONS.isOptionSupported(name)) {
|
||||
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
|
||||
return extendedOptions.getOption(fd, name, isIPv6);
|
||||
return EXTENDED_OPTIONS.getOption(fd, name, isIPv6);
|
||||
}
|
||||
|
||||
// only simple values supported by this method
|
||||
if (type != Integer.class && type != Boolean.class)
|
||||
throw new AssertionError("Should not reach here");
|
||||
throw shouldNotReachHere();
|
||||
|
||||
// map option name to platform level/name
|
||||
OptionKey key = SocketOptionRegistry.findOption(name, family);
|
||||
|
@ -493,7 +486,7 @@ public class Net {
|
|||
public static boolean isFastTcpLoopbackRequested() {
|
||||
String loopbackProp = GetPropertyAction
|
||||
.privilegedGetProperty("jdk.net.useFastTcpLoopback", "false");
|
||||
return loopbackProp.isEmpty() ? true : Boolean.parseBoolean(loopbackProp);
|
||||
return loopbackProp.isEmpty() || Boolean.parseBoolean(loopbackProp);
|
||||
}
|
||||
|
||||
// -- Socket operations --
|
||||
|
@ -522,7 +515,7 @@ public class Net {
|
|||
static FileDescriptor socket(ProtocolFamily family, boolean stream) throws IOException {
|
||||
boolean preferIPv6 = isIPv6Available() &&
|
||||
(family != StandardProtocolFamily.INET);
|
||||
return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback));
|
||||
return IOUtil.newFD(socket0(preferIPv6, stream, false, FAST_LOOPBACK));
|
||||
}
|
||||
|
||||
static FileDescriptor serverSocket(boolean stream) {
|
||||
|
@ -532,10 +525,10 @@ public class Net {
|
|||
static FileDescriptor serverSocket(ProtocolFamily family, boolean stream) {
|
||||
boolean preferIPv6 = isIPv6Available() &&
|
||||
(family != StandardProtocolFamily.INET);
|
||||
return IOUtil.newFD(socket0(preferIPv6, stream, true, fastLoopback));
|
||||
return IOUtil.newFD(socket0(preferIPv6, stream, true, FAST_LOOPBACK));
|
||||
}
|
||||
|
||||
// Due to oddities SO_REUSEADDR on windows reuse is ignored
|
||||
// Due to oddities SO_REUSEADDR on Windows reuse is ignored
|
||||
private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse,
|
||||
boolean fastLoopback);
|
||||
|
||||
|
@ -553,7 +546,7 @@ public class Net {
|
|||
if (addr.isLinkLocalAddress()) {
|
||||
addr = IPAddressUtil.toScopedAddress(addr);
|
||||
}
|
||||
bind0(fd, preferIPv6, exclusiveBind, addr, port);
|
||||
bind0(fd, preferIPv6, EXCLUSIVE_BIND, addr, port);
|
||||
}
|
||||
|
||||
private static native void bind0(FileDescriptor fd, boolean preferIPv6,
|
||||
|
@ -655,7 +648,7 @@ public class Net {
|
|||
/**
|
||||
* Polls a connecting socket to test if the connection has been established.
|
||||
*
|
||||
* @apiNote This method is public to allow it be used by code in jdk.sctp.
|
||||
* @apiNote This method is public to allow it to be used by code in jdk.sctp.
|
||||
*
|
||||
* @param timeout the timeout to wait; 0 to not wait, -1 to wait indefinitely
|
||||
* @return true if connected
|
||||
|
@ -821,17 +814,22 @@ public class Net {
|
|||
String exclBindProp = GetPropertyAction
|
||||
.privilegedGetProperty("sun.net.useExclusiveBind");
|
||||
if (exclBindProp != null) {
|
||||
exclusiveBind = exclBindProp.isEmpty() ?
|
||||
true : Boolean.parseBoolean(exclBindProp);
|
||||
} else if (availLevel == 1) {
|
||||
exclusiveBind = true;
|
||||
EXCLUSIVE_BIND = exclBindProp.isEmpty() || Boolean.parseBoolean(exclBindProp);
|
||||
} else {
|
||||
exclusiveBind = false;
|
||||
EXCLUSIVE_BIND = (availLevel == 1);
|
||||
}
|
||||
} else {
|
||||
exclusiveBind = false;
|
||||
EXCLUSIVE_BIND = false;
|
||||
}
|
||||
|
||||
fastLoopback = isFastTcpLoopbackRequested();
|
||||
FAST_LOOPBACK = isFastTcpLoopbackRequested();
|
||||
|
||||
IPV6_AVAILABLE = isIPv6Available0();
|
||||
SO_REUSEPORT_AVAILABLE = isReusePortAvailable0();
|
||||
}
|
||||
|
||||
private static AssertionError shouldNotReachHere() {
|
||||
return new AssertionError("Should not reach here");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue