You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mi...@apache.org on 2010/10/31 14:14:06 UTC

svn commit: r1029331 - in /lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index: ConcurrentMergeScheduler.java IndexWriter.java MergePolicy.java TermsHash.java

Author: mikemccand
Date: Sun Oct 31 13:14:06 2010
New Revision: 1029331

URL: http://svn.apache.org/viewvc?rev=1029331&view=rev
Log:
LUCENE-2730: fix intermittent deadlock cases

Modified:
    lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
    lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/MergePolicy.java
    lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/TermsHash.java

Modified: lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java?rev=1029331&r1=1029330&r2=1029331&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (original)
+++ lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java Sun Oct 31 13:14:06 2010
@@ -138,11 +138,21 @@ public class ConcurrentMergeScheduler ex
   }
 
   private synchronized int mergeThreadCount() {
+    return mergeThreadCount(false);
+  }
+
+  private synchronized int mergeThreadCount(boolean excludeDone) {
     int count = 0;
     final int numThreads = mergeThreads.size();
-    for(int i=0;i<numThreads;i++)
-      if (((MergeThread) mergeThreads.get(i)).isAlive())
-        count++;
+    for(int i=0;i<numThreads;i++) {
+      MergeThread t = (MergeThread) mergeThreads.get(i);
+      if (t.isAlive()) {
+        MergePolicy.OneMerge runningMerge = t.getRunningMerge();
+        if (!excludeDone || (runningMerge != null && !runningMerge.mergeDone)) {
+          count++;
+        }
+      }
+    }
     return count;
   }
 
@@ -193,7 +203,7 @@ public class ConcurrentMergeScheduler ex
       try {
         synchronized(this) {
           final MergeThread merger;
-          while (mergeThreadCount() >= maxThreadCount) {
+          while (mergeThreadCount(true) >= maxThreadCount) {
             if (verbose())
               message("    too many merge threads running; stalling...");
             try {
@@ -209,8 +219,6 @@ public class ConcurrentMergeScheduler ex
           if (verbose())
             message("  consider merge " + merge.segString(dir));
       
-          assert mergeThreadCount() < maxThreadCount;
-
           // OK to spawn a new merge thread to handle this
           // merge:
           merger = getMergeThread(writer, merge);

Modified: lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/IndexWriter.java?rev=1029331&r1=1029330&r2=1029331&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/IndexWriter.java Sun Oct 31 13:14:06 2010
@@ -5257,6 +5257,12 @@ public class IndexWriter {
       }
     }
 
+    merge.mergeDone = true;
+
+    synchronized(mergeScheduler) {
+      mergeScheduler.notifyAll();
+    }
+
     // Force a sync after commiting the merge.  Once this
     // sync completes then all index files referenced by the
     // current segmentInfos are on stable storage so if the

Modified: lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/MergePolicy.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/MergePolicy.java?rev=1029331&r1=1029330&r2=1029331&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/MergePolicy.java (original)
+++ lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/MergePolicy.java Sun Oct 31 13:14:06 2010
@@ -87,6 +87,8 @@ public abstract class MergePolicy {
     boolean aborted;
     Throwable error;
 
+    volatile boolean mergeDone;     // used by IndexWriter
+
     public OneMerge(SegmentInfos segments, boolean useCompoundFile) {
       if (0 == segments.size())
         throw new RuntimeException("segments must include at least one segment");

Modified: lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/TermsHash.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/TermsHash.java?rev=1029331&r1=1029330&r2=1029331&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/TermsHash.java (original)
+++ lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/index/TermsHash.java Sun Oct 31 13:14:06 2010
@@ -44,8 +44,6 @@ final class TermsHash extends InvertedDo
   final int postingsFreeChunk;
   final DocumentsWriter docWriter;
   
-  private TermsHash primaryTermsHash;
-
   private RawPostingList[] postingsFreeList = new RawPostingList[1];
   private int postingsFreeCount;
   private int postingsAllocCount;
@@ -79,7 +77,10 @@ final class TermsHash extends InvertedDo
     consumer.setFieldInfos(fieldInfos);
   }
 
-  synchronized public void abort() {
+  // NOTE: do not make this sync'd; it's not necessary (DW
+  // ensures all other threads are idle), and it leads to
+  // deadlock
+  public void abort() {
     consumer.abort();
     if (nextTermsHash != null)
       nextTermsHash.abort();