From 4698e4fa18f652019b8f06fef1b2b8813446f5e0 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 03 Jan 2007 16:12:10 +0000
Subject: [PATCH] Update the task backend to properly acquire read locks on task and recurring task entries when evaluating them during search operations, and to acquire write locks for the entries when they are being updated. This should eliminate the possibility of concurrent modification exceptions being thrown in cases where a client issues a search for a task entry at the same time the task entry is being updated within the server.
---
opends/src/server/org/opends/server/backends/task/Task.java | 158 +++++++++++++++++++++++++++++++++++-----------------
1 files changed, 107 insertions(+), 51 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 42c7b90..28c511f 100644
--- a/opends/src/server/org/opends/server/backends/task/Task.java
+++ b/opends/src/server/org/opends/server/backends/task/Task.java
@@ -37,6 +37,7 @@
import java.util.List;
import java.util.TimeZone;
import java.util.UUID;
+import java.util.concurrent.locks.Lock;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -44,6 +45,7 @@
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
@@ -75,6 +77,9 @@
+ // The DN for the task entry.
+ private DN taskEntryDN;
+
// The entry that actually defines this task.
private Entry taskEntry;
@@ -141,8 +146,9 @@
this.taskScheduler = taskScheduler;
this.taskEntry = taskEntry;
+ this.taskEntryDN = taskEntry.getDN();
- String taskDN = taskEntry.getDN().toString();
+ String taskDN = taskEntryDN.toString();
logMessageCounter = 0;
@@ -438,6 +444,20 @@
/**
+ * Retrieves the DN of the entry containing the definition for this task.
+ *
+ * @return The DN of the entry containing the definition for this task.
+ */
+ public final DN getTaskEntryDN()
+ {
+ assert debugEnter(CLASS_NAME, "getTaskEntryDN");
+
+ return taskEntryDN;
+ }
+
+
+
+ /**
* Retrieves the entry containing the definition for this task.
*
* @return The entry containing the definition for this task.
@@ -507,22 +527,32 @@
{
assert debugEnter(CLASS_NAME, "setTaskState", String.valueOf(taskState));
- this.taskState = taskState;
+ Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
- AttributeType type =
- DirectoryServer.getAttributeType(ATTR_TASK_STATE.toLowerCase());
- if (type == null)
+ try
{
- type = DirectoryServer.getDefaultAttributeType(ATTR_TASK_STATE);
+ this.taskState = taskState;
+
+ AttributeType type =
+ DirectoryServer.getAttributeType(ATTR_TASK_STATE.toLowerCase());
+ if (type == null)
+ {
+ type = DirectoryServer.getDefaultAttributeType(ATTR_TASK_STATE);
+ }
+
+ LinkedHashSet<AttributeValue> values =
+ new LinkedHashSet<AttributeValue>();
+ values.add(new AttributeValue(type,
+ new ASN1OctetString(taskState.toString())));
+
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(new Attribute(type, ATTR_TASK_STATE, values));
+ taskEntry.putAttribute(type, attrList);
}
-
- LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
- values.add(new AttributeValue(type,
- new ASN1OctetString(taskState.toString())));
-
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(type, ATTR_TASK_STATE, values));
- taskEntry.putAttribute(type, attrList);
+ finally
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
@@ -574,27 +604,37 @@
assert debugEnter(CLASS_NAME, "setActualStartTime",
String.valueOf(actualStartTime));
- this.actualStartTime = actualStartTime;
+ Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
- AttributeType type = DirectoryServer.getAttributeType(
- ATTR_TASK_ACTUAL_START_TIME.toLowerCase());
- if (type == null)
+ try
{
- type = DirectoryServer.getDefaultAttributeType(
- ATTR_TASK_ACTUAL_START_TIME);
+ this.actualStartTime = actualStartTime;
+
+ AttributeType type = DirectoryServer.getAttributeType(
+ ATTR_TASK_ACTUAL_START_TIME.toLowerCase());
+ if (type == null)
+ {
+ type = DirectoryServer.getDefaultAttributeType(
+ ATTR_TASK_ACTUAL_START_TIME);
+ }
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_UTC_TIME);
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date d = new Date(actualStartTime);
+ ASN1OctetString s = new ASN1OctetString(dateFormat.format(d));
+
+ LinkedHashSet<AttributeValue> values =
+ new LinkedHashSet<AttributeValue>();
+ values.add(new AttributeValue(type, s));
+
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(new Attribute(type, ATTR_TASK_ACTUAL_START_TIME, values));
+ taskEntry.putAttribute(type, attrList);
}
-
- SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_UTC_TIME);
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- Date d = new Date(actualStartTime);
- ASN1OctetString s = new ASN1OctetString(dateFormat.format(d));
-
- LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
- values.add(new AttributeValue(type, s));
-
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(type, ATTR_TASK_ACTUAL_START_TIME, values));
- taskEntry.putAttribute(type, attrList);
+ finally
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
@@ -629,26 +669,37 @@
assert debugEnter(CLASS_NAME, "setCompletionTime",
String.valueOf(completionTime));
- this.completionTime = completionTime;
+ Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
- AttributeType type = DirectoryServer.getAttributeType(
- ATTR_TASK_COMPLETION_TIME.toLowerCase());
- if (type == null)
+ try
{
- type = DirectoryServer.getDefaultAttributeType(ATTR_TASK_COMPLETION_TIME);
+ this.completionTime = completionTime;
+
+ AttributeType type = DirectoryServer.getAttributeType(
+ ATTR_TASK_COMPLETION_TIME.toLowerCase());
+ if (type == null)
+ {
+ type =
+ DirectoryServer.getDefaultAttributeType(ATTR_TASK_COMPLETION_TIME);
+ }
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_UTC_TIME);
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date d = new Date(completionTime);
+ ASN1OctetString s = new ASN1OctetString(dateFormat.format(d));
+
+ LinkedHashSet<AttributeValue> values =
+ new LinkedHashSet<AttributeValue>();
+ values.add(new AttributeValue(type, s));
+
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(new Attribute(type, ATTR_TASK_COMPLETION_TIME, values));
+ taskEntry.putAttribute(type, attrList);
}
-
- SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_UTC_TIME);
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- Date d = new Date(completionTime);
- ASN1OctetString s = new ASN1OctetString(dateFormat.format(d));
-
- LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
- values.add(new AttributeValue(type, s));
-
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(type, ATTR_TASK_COMPLETION_TIME, values));
- taskEntry.putAttribute(type, attrList);
+ finally
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
@@ -756,10 +807,11 @@
String.valueOf(severity), String.valueOf(messageID),
String.valueOf(messageString));
- StringBuilder buffer = new StringBuilder();
+ Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
- synchronized (logMessages)
+ try
{
+ StringBuilder buffer = new StringBuilder();
buffer.append("[");
buffer.append(TimeThread.getLocalTime());
buffer.append("] severity=\"");
@@ -809,6 +861,10 @@
attrList.add(new Attribute(type, ATTR_TASK_LOG_MESSAGES, values));
}
}
+ finally
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
--
Gitblit v1.10.0