Index: src/java/org/apache/lucene/index/MergePolicy.java =================================================================== --- src/java/org/apache/lucene/index/MergePolicy.java (revision 1029061) +++ src/java/org/apache/lucene/index/MergePolicy.java (working copy) @@ -87,6 +87,8 @@ 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"); Index: src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java =================================================================== --- src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (revision 1029061) +++ src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (working copy) @@ -138,11 +138,21 @@ } 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= maxThreadCount) { + while (mergeThreadCount(true) >= maxThreadCount) { if (verbose()) message(" too many merge threads running; stalling..."); try { @@ -209,8 +219,6 @@ 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); Index: src/java/org/apache/lucene/index/TermsHash.java =================================================================== --- src/java/org/apache/lucene/index/TermsHash.java (revision 1029061) +++ src/java/org/apache/lucene/index/TermsHash.java (working copy) @@ -44,8 +44,6 @@ 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 @@ 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(); Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 1029065) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -5257,6 +5257,12 @@ } } + 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