From 855f77aec2c9ca6a91be51361673fda4b58b3adf Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 02 Aug 2007 21:47:09 +0000
Subject: [PATCH] Fix a potential deadlock in the task code that could occur if a client tried to retrieve the task entry at the same time that it was being updated.
---
opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java | 56 ++++++++++++++++++++++++----
opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskScheduler.java | 13 ++++++
2 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
index 39ae64d..8879aba 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
@@ -555,7 +555,14 @@
*/
void setTaskState(TaskState taskState)
{
- Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
+ // 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
{
@@ -579,7 +586,10 @@
}
finally
{
- taskScheduler.unlockEntry(taskEntryDN, lock);
+ if (needLock)
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
}
@@ -625,7 +635,14 @@
*/
private void setActualStartTime(long actualStartTime)
{
- Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
+ // 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
{
@@ -654,7 +671,10 @@
}
finally
{
- taskScheduler.unlockEntry(taskEntryDN, lock);
+ if (needLock)
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
}
@@ -685,7 +705,14 @@
*/
private void setCompletionTime(long completionTime)
{
- Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
+ // 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
{
@@ -714,7 +741,10 @@
}
finally
{
- taskScheduler.unlockEntry(taskEntryDN, lock);
+ if (needLock)
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
}
@@ -879,7 +909,14 @@
public void addLogMessage(ErrorLogSeverity severity, int messageID,
String messageString)
{
- Lock lock = taskScheduler.writeLockEntry(taskEntryDN);
+ // 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
{
@@ -935,7 +972,10 @@
}
finally
{
- taskScheduler.unlockEntry(taskEntryDN, lock);
+ if (needLock)
+ {
+ taskScheduler.unlockEntry(taskEntryDN, lock);
+ }
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskScheduler.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
index 6bdebcf..9160631 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -1468,6 +1468,19 @@
/**
+ * Indicates whether the current thread already holds a lock on the scheduler.
+ *
+ * @return {@code true} if the current thread holds the scheduler lock, or
+ * {@code false} if not.
+ */
+ boolean holdsSchedulerLock()
+ {
+ return schedulerLock.isHeldByCurrentThread();
+ }
+
+
+
+ /**
* Attempts to acquire a write lock on the specified entry, trying as many
* times as necessary until the lock has been acquired.
*
--
Gitblit v1.10.0