Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1150663) +++ lucene/CHANGES.txt (working copy) @@ -26,6 +26,10 @@ suppressed exceptions in the original exception, so stack trace will contain them. (Uwe Schindler) +* LUCENE-3339: Fixed deadlock case when multiple threads use the new + block-add (IndexWriter.add/updateDocuments) methods. (Robert Muir, + Mike McCandless) + New Features * LUCENE-3290: Added FieldInvertState.numUniqueTerms Index: lucene/src/java/org/apache/lucene/index/DocumentsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocumentsWriter.java (revision 1150663) +++ lucene/src/java/org/apache/lucene/index/DocumentsWriter.java (working copy) @@ -843,6 +843,12 @@ final int startDocID = docState.docID; int docID = startDocID; + // We must delay pausing until the full doc block is + // added, else we can hit deadlock if more than one + // thread is adding a block and we need to pause when + // both are only part way done: + boolean doPauseWaitQueue = false; + //System.out.println(Thread.currentThread().getName() + ": A " + docCount); for(Document doc : docs) { docState.doc = doc; @@ -873,14 +879,11 @@ assert perDoc == null || perDoc.docID == docState.docID; final boolean doPause; if (perDoc != null) { - doPause = waitQueue.add(perDoc); + doPauseWaitQueue |= waitQueue.add(perDoc); } else { skipDocWriter.docID = docState.docID; - doPause = waitQueue.add(skipDocWriter); + doPauseWaitQueue |= waitQueue.add(skipDocWriter); } - if (doPause) { - waitForWaitQueue(); - } } success = true; @@ -937,6 +940,10 @@ } } } + + if (doPauseWaitQueue) { + waitForWaitQueue(); + } } //System.out.println(Thread.currentThread().getName() + ": A " + docCount);