From e5e4ea1dfa436ac42413a4d9b3b1279354b7cc3b Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 16 May 2014 08:22:41 +0000
Subject: [PATCH] Fixing JEChangeNumberIndexDBTest random tests. JE was throwing exception when the thread accessing it had been interrupted which happens frequently on single core machines. The solution is to replace the use of Thread.sleep(long) + Thread.interrupt() with Object.wait(long) + Object.notify() on thread shutdown.
---
opends/src/server/org/opends/server/replication/server/changelog/je/JEChangelogDB.java | 53 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/server/changelog/je/JEChangelogDB.java b/opends/src/server/org/opends/server/replication/server/changelog/je/JEChangelogDB.java
index f3507e0..a9f69ba 100644
--- a/opends/src/server/org/opends/server/replication/server/changelog/je/JEChangelogDB.java
+++ b/opends/src/server/org/opends/server/replication/server/changelog/je/JEChangelogDB.java
@@ -385,13 +385,11 @@
if (indexer != null)
{
indexer.initiateShutdown();
- indexer.interrupt();
}
final ChangelogDBPurger purger = cnPurger.getAndSet(null);
if (purger != null)
{
purger.initiateShutdown();
- purger.interrupt();
}
try
@@ -838,17 +836,14 @@
oldestNotPurgedCSN = localCNIndexDB.purgeUpTo(purgeCSN);
if (oldestNotPurgedCSN == null)
{ // shutdown may have been initiated...
- if (!isShutdownInitiated())
- {
- // ... or the change number index DB is empty,
- // wait for new changes to come in.
+ // ... or the change number index DB is empty,
+ // wait for new changes to come in.
- // Note we cannot sleep for as long as the purge delay
- // (3 days default), because we might receive late updates
- // that will have to be purged before the purge delay elapses.
- // This can particularly happen in case of network partitions.
- sleep(DEFAULT_SLEEP);
- }
+ // Note we cannot sleep for as long as the purge delay
+ // (3 days default), because we might receive late updates
+ // that will have to be purged before the purge delay elapses.
+ // This can particularly happen in case of network partitions.
+ jeFriendlySleep(DEFAULT_SLEEP);
continue;
}
}
@@ -864,7 +859,7 @@
latestPurgeDate = purgeTimestamp;
- sleep(computeSleepTimeUntilNextPurge(oldestNotPurgedCSN));
+ jeFriendlySleep(computeSleepTimeUntilNextPurge(oldestNotPurgedCSN));
}
catch (InterruptedException e)
{
@@ -882,6 +877,33 @@
}
}
+ /**
+ * This method implements a sleep() that is friendly to Berkeley JE.
+ * <p>
+ * Originally, {@link Thread#sleep(long)} was used , but waking up a
+ * sleeping threads required calling {@link Thread#interrupt()}, and JE
+ * threw exceptions when invoked on interrupted threads.
+ * <p>
+ * The solution is to replace:
+ * <ol>
+ * <li> {@link Thread#sleep()} with {@link Object#wait(long)}</li>
+ * <li> {@link Thread#interrupt()} with {@link Object#notify()}</li>
+ * </ol>
+ */
+ private void jeFriendlySleep(long millis) throws InterruptedException
+ {
+ if (!isShutdownInitiated())
+ {
+ synchronized (this)
+ {
+ if (!isShutdownInitiated())
+ {
+ wait(millis);
+ }
+ }
+ }
+ }
+
private long computeSleepTimeUntilNextPurge(CSN notPurgedCSN)
{
final long nextPurgeTime = notPurgedCSN.getTime();
@@ -900,7 +922,10 @@
public void initiateShutdown()
{
super.initiateShutdown();
- this.interrupt(); // wake up the purger thread for faster shutdown
+ synchronized (this)
+ {
+ notify(); // wake up the purger thread for faster shutdown
+ }
}
}
}
--
Gitblit v1.10.0