< prev index next >

src/java.base/share/classes/java/net/InetAddress.java

Print this page
@@ -52,14 +52,14 @@
  import java.util.concurrent.atomic.AtomicLong;
  import java.util.Arrays;
  import java.util.concurrent.locks.ReentrantLock;
  import java.util.stream.Stream;
  
- import jdk.internal.misc.VM;
- 
  import jdk.internal.access.JavaNetInetAddressAccess;
  import jdk.internal.access.SharedSecrets;
+ import jdk.internal.misc.Blocker;
+ import jdk.internal.misc.VM;
  import jdk.internal.vm.annotation.Stable;
  import sun.net.ResolverProviderConfiguration;
  import sun.security.action.*;
  import sun.net.InetAddressCachePolicy;
  import sun.net.util.IPAddressUtil;

@@ -966,21 +966,23 @@
  
      // a name service lookup based Addresses implementation which replaces itself
      // in cache when the result is obtained
      private static final class NameServiceAddresses implements Addresses {
          private final String host;
+         private final ReentrantLock lookupLock = new ReentrantLock();
  
          NameServiceAddresses(String host) {
              this.host = host;
          }
  
          @Override
          public InetAddress[] get() throws UnknownHostException {
              Addresses addresses;
              // only one thread is doing lookup to name service
              // for particular host at any time.
-             synchronized (this) {
+             lookupLock.lock();
+             try {
                  // re-check that we are still us + re-install us if slot empty
                  addresses = cache.putIfAbsent(host, this);
                  if (addresses == null) {
                      // this can happen when we were replaced by CachedAddresses in
                      // some other thread, then CachedAddresses expired and were

@@ -1024,10 +1026,12 @@
                          throw ex == null ? new UnknownHostException(host) : ex;
                      }
                      return inetAddresses;
                  }
                  // else addresses != this
+             } finally {
+                 lookupLock.unlock();
              }
              // delegate to different addresses when we are already replaced
              // but outside of synchronized block to avoid any chance of dead-locking
              return addresses.get();
          }

@@ -1043,20 +1047,29 @@
  
          public Stream<InetAddress> lookupByName(String host, LookupPolicy policy)
                  throws UnknownHostException {
              Objects.requireNonNull(host);
              Objects.requireNonNull(policy);
-             return Arrays.stream(impl.lookupAllHostAddr(host, policy));
+             InetAddress[] addrs;
+             if (Thread.currentThread().isVirtual()) {
+                 addrs = Blocker.managedBlock(() -> impl.lookupAllHostAddr(host, policy));
+             } else {
+                 addrs = impl.lookupAllHostAddr(host, policy);
+             }
+             return Arrays.stream(addrs);
          }
  
-         public String lookupByAddress(byte[] addr)
-                 throws UnknownHostException {
+         public String lookupByAddress(byte[] addr) throws UnknownHostException {
              Objects.requireNonNull(addr);
              if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
                  throw new IllegalArgumentException("Invalid address length");
              }
-             return impl.getHostByAddr(addr);
+             if (Thread.currentThread().isVirtual()) {
+                 return Blocker.managedBlock(() -> impl.getHostByAddr(addr));
+             } else {
+                 return impl.getHostByAddr(addr);
+             }
          }
      }
  
      /**
       * The HostsFileResolver provides host address mapping
< prev index next >