From 25dac9c266bda7e12badf795984da0cfcf2dff41 Mon Sep 17 00:00:00 2001
From: gbellato <gbellato@localhost>
Date: Mon, 27 Aug 2007 11:31:55 +0000
Subject: [PATCH] fix for issue 2150  : ConcurrentModificationException in InitializeTask

---
 opends/src/server/org/opends/server/backends/task/Task.java   |   42 +++++++++++++++++++++
 opends/src/server/org/opends/server/tasks/InitializeTask.java |   76 +++++++------------------------------
 2 files changed, 57 insertions(+), 61 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/task/Task.java b/opends/src/server/org/opends/server/backends/task/Task.java
index 10a9cd7..1a83f2d 100644
--- a/opends/src/server/org/opends/server/backends/task/Task.java
+++ b/opends/src/server/org/opends/server/backends/task/Task.java
@@ -53,6 +53,8 @@
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ModificationType;
 
 
 import org.opends.server.types.InitializationException;
@@ -594,6 +596,46 @@
     }
   }
 
+  /**
+   * Replaces an attribute values of the task entry.
+   *
+   * @param  name  The name of the attribute that must be replaced.
+   *
+   * @param  value The value that must replace the previous values of the
+   *               attribute.
+   *
+   * @throws DirectoryException When an error occurs.
+   */
+  protected void replaceAttributeValue(String name, String value)
+  throws DirectoryException
+  {
+    // We only need to grab the entry-level lock if we don't already hold the
+    // broader scheduler lock.
+    boolean needLock = (! taskScheduler.holdsSchedulerLock());
+    Lock lock = null;
+    if (needLock)
+    {
+      lock = taskScheduler.writeLockEntry(taskEntryDN);
+    }
+
+    try
+    {
+      Entry taskEntry = getTaskEntry();
+
+      ArrayList<Modification> modifications = new ArrayList<Modification>();
+      modifications.add(new Modification(ModificationType.REPLACE,
+          new Attribute(name, value)));
+
+      taskEntry.applyModifications(modifications);
+    }
+    finally
+    {
+      if (needLock)
+      {
+        taskScheduler.unlockEntry(taskEntryDN, lock);
+      }
+    }
+  }
 
 
   /**
diff --git a/opends/src/server/org/opends/server/tasks/InitializeTask.java b/opends/src/server/org/opends/server/tasks/InitializeTask.java
index 603c2c7..0524545 100644
--- a/opends/src/server/org/opends/server/tasks/InitializeTask.java
+++ b/opends/src/server/org/opends/server/tasks/InitializeTask.java
@@ -25,29 +25,24 @@
  *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
 package org.opends.server.tasks;
-import org.opends.messages.MessageBuilder;
-
 import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.core.DirectoryServer.getAttributeType;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.loggers.debug.DebugLogger.getTracer;
+
 import java.util.List;
 
+import org.opends.messages.MessageBuilder;
+import org.opends.messages.TaskMessages;
 import org.opends.server.backends.task.Task;
 import org.opends.server.backends.task.TaskState;
-import org.opends.messages.TaskMessages;
-import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.replication.plugin.ReplicationDomain;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
 import org.opends.server.types.DN;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.Entry;
-import org.opends.server.types.Modification;
-import org.opends.server.types.ModificationType;
 import org.opends.server.types.ResultCode;
 
 /**
@@ -122,8 +117,8 @@
     String sourceString = TaskUtils.getSingleValueString(attrList);
     source = domain.decodeSource(sourceString);
 
-    createAttribute(ATTR_TASK_INITIALIZE_LEFT, 0);
-    createAttribute(ATTR_TASK_INITIALIZE_DONE, 0);
+    replaceAttributeValue(ATTR_TASK_INITIALIZE_LEFT, String.valueOf(0));
+    replaceAttributeValue(ATTR_TASK_INITIALIZE_DONE, String.valueOf(0));
   }
 
   /**
@@ -148,12 +143,15 @@
         while (initState == TaskState.RUNNING)
         {
           initState.wait(1000);
-          updateAttribute(ATTR_TASK_INITIALIZE_LEFT, left);
-          updateAttribute(ATTR_TASK_INITIALIZE_DONE, total-left);
+          replaceAttributeValue(
+              ATTR_TASK_INITIALIZE_LEFT, String.valueOf(left));
+          replaceAttributeValue(
+              ATTR_TASK_INITIALIZE_DONE, String.valueOf(total-left));
         }
       }
-      updateAttribute(ATTR_TASK_INITIALIZE_LEFT, left);
-      updateAttribute(ATTR_TASK_INITIALIZE_DONE, total-left);
+      replaceAttributeValue(ATTR_TASK_INITIALIZE_LEFT, String.valueOf(left));
+      replaceAttributeValue(
+          ATTR_TASK_INITIALIZE_DONE, String.valueOf(total-left));
     }
     catch(InterruptedException ie) {}
     catch(DirectoryException de)
@@ -199,50 +197,6 @@
     {}
   }
 
-  /**
-   * Create a new attribute the task entry.
-   * @param name The name of the attribute
-   * @param value The value to store
-   */
-  protected void createAttribute(String name, long value)
-  {
-    AttributeType type;
-    LinkedHashSet<AttributeValue> values =
-      new LinkedHashSet<AttributeValue>();
-
-    Entry taskEntry = getTaskEntry();
-    try
-    {
-      type = getAttributeType(name, true);
-      values.add(new AttributeValue(type,
-          new ASN1OctetString(String.valueOf(value))));
-      ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
-      attrList.add(new Attribute(type, name,values));
-      taskEntry.putAttribute(type, attrList);
-    }
-    finally
-    {
-      // taskScheduler.unlockEntry(taskEntryDN, lock);
-    }
-  }
-
-  /**
-   * Update an attribute for this task.
-   * @param name The name of the attribute.
-   * @param value The value.
-   * @throws DirectoryException When an error occurs.
-   */
-  protected void updateAttribute(String name, long value)
-  throws DirectoryException
-  {
-    Entry taskEntry = getTaskEntry();
-
-    ArrayList<Modification> modifications = new ArrayList<Modification>();
-    modifications.add(new Modification(ModificationType.REPLACE,
-        new Attribute(name, String.valueOf(value))));
-
-    taskEntry.applyModifications(modifications);
-  }
 
   /**
    * Set the total number of entries expected to be imported.

--
Gitblit v1.10.0