From 7f2a4c9b822ba82cc0f3ad2ca84921bc02d3bb22 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 06 Sep 2013 13:05:25 +0000
Subject: [PATCH] Fix OPENDJ-1127: Replication server reconnect thread consumes too much CPU

---
 opends/src/server/org/opends/server/util/StaticUtils.java |   54 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/opends/src/server/org/opends/server/util/StaticUtils.java b/opends/src/server/org/opends/server/util/StaticUtils.java
index 94df1c0..ce1a89b 100644
--- a/opends/src/server/org/opends/server/util/StaticUtils.java
+++ b/opends/src/server/org/opends/server/util/StaticUtils.java
@@ -4544,39 +4544,45 @@
    */
   public static boolean isLocalAddress(InetAddress address)
   {
-    if (address.isLoopbackAddress())
+    return address.isLoopbackAddress() || getLocalAddresses().contains(address);
+  }
+
+  // Time-stamp acts as memory barrier for networkInterfaces.
+  private static final long CACHED_LOCAL_ADDRESSES_TIMEOUT_MS = 30 * 1000;
+  private static volatile long localAddressesTimeStamp = 0;
+  private static Set<InetAddress> localAddresses = new HashSet<InetAddress>();
+
+  private static Set<InetAddress> getLocalAddresses()
+  {
+    final long currentTimeStamp = System.currentTimeMillis();
+    if (localAddressesTimeStamp
+        < (currentTimeStamp - CACHED_LOCAL_ADDRESSES_TIMEOUT_MS))
     {
-      return true;
-    }
-    else
-    {
-      Enumeration<NetworkInterface> i;
+      // Refresh the cache.
       try
       {
-        i = NetworkInterface.getNetworkInterfaces();
+        final Enumeration<NetworkInterface> i = NetworkInterface
+            .getNetworkInterfaces();
+        final Set<InetAddress> newLocalAddresses = new HashSet<InetAddress>();
+        while (i.hasMoreElements())
+        {
+          NetworkInterface n = i.nextElement();
+          Enumeration<InetAddress> j = n.getInetAddresses();
+          while (j.hasMoreElements())
+          {
+            newLocalAddresses.add(j.nextElement());
+          }
+        }
+        localAddresses = newLocalAddresses;
       }
       catch (SocketException e)
       {
-        // Unable to determine whether the address is local.
+        // Ignore and keep the old set.
         TRACER.debugCaught(DebugLogLevel.WARNING, e);
-        return false;
       }
-
-      while (i.hasMoreElements())
-      {
-        NetworkInterface n = i.nextElement();
-        Enumeration<InetAddress> j = n.getInetAddresses();
-        while (j.hasMoreElements())
-        {
-          InetAddress localAddress = j.nextElement();
-          if (localAddress.equals(address))
-          {
-            return true;
-          }
-        }
-      }
-      return false;
+      localAddressesTimeStamp = currentTimeStamp; // Publishes.
     }
+    return localAddresses;
   }
 
   /**

--
Gitblit v1.10.0