735 |
734 |
736 if (policy != InetAddressCachePolicy.FOREVER) { |
735 if (policy != InetAddressCachePolicy.FOREVER) { |
737 |
736 |
738 // As we iterate in insertion order we can |
737 // As we iterate in insertion order we can |
739 // terminate when a non-expired entry is found. |
738 // terminate when a non-expired entry is found. |
740 LinkedList<String> expired = new LinkedList<String>(); |
739 LinkedList<String> expired = new LinkedList<>(); |
741 long now = System.currentTimeMillis(); |
740 long now = System.currentTimeMillis(); |
742 for (String key : cache.keySet()) { |
741 for (String key : cache.keySet()) { |
743 CacheEntry entry = cache.get(key); |
742 CacheEntry entry = cache.get(key); |
744 |
743 |
745 if (entry.expiration >= 0 && entry.expiration < now) { |
744 if (entry.expiration >= 0 && entry.expiration < now) { |
1225 // addressCache for any reason, |
1224 // addressCache for any reason, |
1226 // it should add the host in the |
1225 // it should add the host in the |
1227 // lookupTable and return null so the |
1226 // lookupTable and return null so the |
1228 // following code would do a lookup itself. |
1227 // following code would do a lookup itself. |
1229 if ((addresses = checkLookupTable(host)) == null) { |
1228 if ((addresses = checkLookupTable(host)) == null) { |
1230 // This is the first thread which looks up the addresses |
1229 try { |
1231 // this host or the cache entry for this host has been |
1230 // This is the first thread which looks up the addresses |
1232 // expired so this thread should do the lookup. |
1231 // this host or the cache entry for this host has been |
1233 for (NameService nameService : nameServices) { |
1232 // expired so this thread should do the lookup. |
1234 try { |
1233 for (NameService nameService : nameServices) { |
1235 /* |
1234 try { |
1236 * Do not put the call to lookup() inside the |
1235 /* |
1237 * constructor. if you do you will still be |
1236 * Do not put the call to lookup() inside the |
1238 * allocating space when the lookup fails. |
1237 * constructor. if you do you will still be |
1239 */ |
1238 * allocating space when the lookup fails. |
1240 |
1239 */ |
1241 addresses = nameService.lookupAllHostAddr(host); |
1240 |
1242 success = true; |
1241 addresses = nameService.lookupAllHostAddr(host); |
1243 break; |
|
1244 } catch (UnknownHostException uhe) { |
|
1245 if (host.equalsIgnoreCase("localhost")) { |
|
1246 InetAddress[] local = new InetAddress[] { impl.loopbackAddress() }; |
|
1247 addresses = local; |
|
1248 success = true; |
1242 success = true; |
1249 break; |
1243 break; |
1250 } |
1244 } catch (UnknownHostException uhe) { |
1251 else { |
1245 if (host.equalsIgnoreCase("localhost")) { |
1252 addresses = unknown_array; |
1246 InetAddress[] local = new InetAddress[] { impl.loopbackAddress() }; |
1253 success = false; |
1247 addresses = local; |
1254 ex = uhe; |
1248 success = true; |
|
1249 break; |
|
1250 } |
|
1251 else { |
|
1252 addresses = unknown_array; |
|
1253 success = false; |
|
1254 ex = uhe; |
|
1255 } |
1255 } |
1256 } |
1256 } |
1257 } |
1257 } |
1258 |
1258 |
1259 // Cache the addresses. |
1259 // Cache the addresses. |
1260 cacheAddresses(host, addresses, success); |
1260 cacheAddresses(host, addresses, success); |
1261 if (!success && ex != null) |
1261 // Delete the host from the lookupTable, and |
1262 throw ex; |
1262 // notify all threads waiting for the monitor |
1263 } finally { |
1263 // for lookupTable. |
1264 // Delete host from the lookupTable and notify |
1264 updateLookupTable(host); |
1265 // all threads waiting on the lookupTable monitor. |
1265 if (!success && ex != null) |
1266 updateLookupTable(host); |
1266 throw ex; |
1267 } |
1267 } |
1268 } |
1268 |
1269 |
1269 return addresses; |
1270 return addresses; |
1270 } |
1271 } |
1271 |
1272 |
1272 |
1273 |
1273 private static InetAddress[] checkLookupTable(String host) { |
1274 private static InetAddress[] checkLookupTable(String host) { |
1274 // make sure addresses is null. |
|
1275 InetAddress[] addresses = null; |
|
1276 |
|
1277 synchronized (lookupTable) { |
1275 synchronized (lookupTable) { |
1278 // If the host isn't in the lookupTable, add it in the |
1276 // If the host isn't in the lookupTable, add it in the |
1279 // lookuptable and return null. The caller should do |
1277 // lookuptable and return null. The caller should do |
1280 // the lookup. |
1278 // the lookup. |
1281 if (lookupTable.containsKey(host) == false) { |
1279 if (lookupTable.containsKey(host) == false) { |
1282 lookupTable.put(host, null); |
1280 lookupTable.put(host, null); |
1283 return addresses; |
1281 return null; |
1284 } |
1282 } |
1285 |
1283 |
1286 // If the host is in the lookupTable, it means that another |
1284 // If the host is in the lookupTable, it means that another |
1287 // thread is trying to look up the addresses of this host. |
1285 // thread is trying to look up the addresses of this host. |
1288 // This thread should wait. |
1286 // This thread should wait. |
1296 |
1294 |
1297 // The other thread has finished looking up the addresses of |
1295 // The other thread has finished looking up the addresses of |
1298 // the host. This thread should retry to get the addresses |
1296 // the host. This thread should retry to get the addresses |
1299 // from the addressCache. If it doesn't get the addresses from |
1297 // from the addressCache. If it doesn't get the addresses from |
1300 // the cache, it will try to look up the addresses itself. |
1298 // the cache, it will try to look up the addresses itself. |
1301 addresses = getCachedAddresses(host); |
1299 InetAddress[] addresses = getCachedAddresses(host); |
1302 if (addresses == null) { |
1300 if (addresses == null) { |
1303 synchronized (lookupTable) { |
1301 synchronized (lookupTable) { |
1304 lookupTable.put(host, null); |
1302 lookupTable.put(host, null); |
|
1303 return null; |
1305 } |
1304 } |
1306 } |
1305 } |
1307 |
1306 |
1308 return addresses; |
1307 return addresses; |
1309 } |
1308 } |