From 420d0685be611af4544bcce545a380b9298c0d6a Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 28 May 2010 17:31:16 +0000
Subject: [PATCH] Fix for issue #4514 and #4533. Resolved some possible lock contention in ReplicationServerDomain, resulting in errors in logs. 

---
 opends/src/server/org/opends/server/replication/server/DataServerHandler.java       |   25 ++++--------
 opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java   |   19 +++++++--
 opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java |   60 +++++++++++++++++++-----------
 3 files changed, 61 insertions(+), 43 deletions(-)

diff --git a/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java b/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
index c5e3e2a..e472a43 100644
--- a/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
+++ b/opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -3632,11 +3632,20 @@
     }
     if (search.getResultCode() != ResultCode.SUCCESS)
     {
-      Message message = ERR_SEARCHING_GENERATION_ID.get(
-          search.getResultCode().getResultCodeName() + " " +
-          search.getErrorMessage(),
-          baseDn.toString());
-      logError(message);
+      if (search.getResultCode() == ResultCode.NO_SUCH_OBJECT)
+      {
+        // nothing initialized yet
+        // don't log an error generationID will be computed.
+      }
+      else
+      {
+        //
+        Message message = ERR_SEARCHING_GENERATION_ID.get(
+            search.getResultCode().getResultCodeName() + " " +
+            search.getErrorMessage(),
+            baseDn.toString());
+        logError(message);
+      }
     }
     else
     {
diff --git a/opends/src/server/org/opends/server/replication/server/DataServerHandler.java b/opends/src/server/org/opends/server/replication/server/DataServerHandler.java
index 2b49300..1e2740d 100644
--- a/opends/src/server/org/opends/server/replication/server/DataServerHandler.java
+++ b/opends/src/server/org/opends/server/replication/server/DataServerHandler.java
@@ -142,27 +142,20 @@
           // method. This would lead to a reentrant lock which we do not want.
           // So simply close the session, this will make the hang up appear
           // after the reader thread that took the RSD lock realeases it.
-          try
+          if (session != null)
           {
-            if (session != null)
+            // V4 protocol introduces a StopMsg to properly close the
+            // connection between servers
+            if (protocolVersion >= ProtocolVersion.REPLICATION_PROTOCOL_V4)
             {
-              // V4 protocol introduces a StopMsg to properly close the
-              // connection between servers
-              if (protocolVersion >= ProtocolVersion.REPLICATION_PROTOCOL_V4)
+              try
               {
-                try
-                {
-                  session.publish(new StopMsg());
-                } catch (IOException ioe)
-                {
-                  // Anyway, going to close session, so nothing to do
-                }
+                session.publish(new StopMsg());
+              } catch (IOException ioe)
+              {
+                // Anyway, going to close session, so nothing to do
               }
-              session.close();
             }
-          } catch (IOException e)
-          {
-            // ignore
           }
 
           // NOT_CONNECTED_STATUS is the last one in RS session life: handler
diff --git a/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java b/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
index 2c6f204..5137ba4 100644
--- a/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
+++ b/opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
@@ -2110,10 +2110,13 @@
    *
    * @param generationId The new value of generationId.
    */
-  synchronized public void initGenerationID(long generationId)
+  public void initGenerationID(long generationId)
   {
-    this.generationId = generationId;
-    this.generationIdSavedStatus = true;
+    synchronized (generationIDLock)
+    {
+      this.generationId = generationId;
+      this.generationIdSavedStatus = true;
+    }
   }
 
   /**
@@ -2124,21 +2127,22 @@
    * @param savedStatus  The saved status of the generationId.
    * @return The old generation id
    */
-  synchronized public long changeGenerationId(long generationId,
-    boolean savedStatus)
+  public long changeGenerationId(long generationId, boolean savedStatus)
   {
-    long oldGenerationId = this.generationId;
-
-    if (this.generationId != generationId)
+    synchronized (generationIDLock)
     {
-      // we are changing of genId
-      clearDbs();
+      long oldGenerationId = this.generationId;
 
-      this.generationId = generationId;
-      this.generationIdSavedStatus = savedStatus;
+      if (this.generationId != generationId)
+      {
+        // we are changing of genId
+        clearDbs();
+
+        this.generationId = generationId;
+        this.generationIdSavedStatus = savedStatus;
+      }
+      return oldGenerationId;
     }
-
-    return oldGenerationId;
   }
 
   /**
@@ -2564,18 +2568,20 @@
    * @return The monitor data.
    * @throws DirectoryException When an error occurs.
    */
-  synchronized protected MonitorData computeMonitorData(
-      boolean updateMonitorData)
+  protected MonitorData computeMonitorData(boolean updateMonitorData)
     throws DirectoryException
   {
-    if (updateMonitorData)
+    synchronized (monitoringLock)
     {
-      // Update the monitorData of ALL domains if this was necessary.
-      replicationServer.computeMonitorData();
-    }
+      if (updateMonitorData)
+      {
+        // Update the monitorData of ALL domains if this was necessary.
+        replicationServer.computeMonitorData();
+      }
 
-    // Returns the monitorData of THIS domain
-    return monitorData;
+      // Returns the monitorData of THIS domain
+      return monitorData;
+    }
   }
 
   /**
@@ -2859,6 +2865,16 @@
   private ReentrantLock lock = new ReentrantLock();
 
   /**
+   * This lock is used to protect the monitoring computing.
+   */
+  private final Object monitoringLock = new Object();
+
+  /**
+   * This lock is used to protect the generationid variable.
+   */
+  private final Object generationIDLock = new Object();
+
+  /**
    * Tests if the current thread has the lock on this domain.
    * @return True if the current thread has the lock.
    */

--
Gitblit v1.10.0