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 2009/02/24 11:40:20 UTC
svn commit: r747328 - in /lucene/java/branches/lucene_2_4: ./ CHANGES.txt
src/java/org/apache/lucene/index/IndexWriter.java
Author: mikemccand
Date: Tue Feb 24 10:40:19 2009
New Revision: 747328
URL: http://svn.apache.org/viewvc?rev=747328&view=rev
Log:
LUCENE-1547: fix rare thread hazard in IndexWriter.commit()
Modified:
lucene/java/branches/lucene_2_4/ (props changed)
lucene/java/branches/lucene_2_4/CHANGES.txt
lucene/java/branches/lucene_2_4/src/java/org/apache/lucene/index/IndexWriter.java
Propchange: lucene/java/branches/lucene_2_4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Feb 24 10:40:19 2009
@@ -1 +1 @@
-/lucene/java/trunk:708549,709456,712233,718540,719716,723149,734415,735043,746661
+/lucene/java/trunk:708549,709456,712233,718540,719716,723149,734415,735043,746661,747251
Modified: lucene/java/branches/lucene_2_4/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_4/CHANGES.txt?rev=747328&r1=747327&r2=747328&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_4/CHANGES.txt (original)
+++ lucene/java/branches/lucene_2_4/CHANGES.txt Tue Feb 24 10:40:19 2009
@@ -47,6 +47,9 @@
11. LUCENE-1544: Fix deadlock in IndexWriter.addIndexes(IndexReader[]).
(Mike McCandless via Doug Sale)
+12. LUCENE-1547: Fix rare thread safety issue if two threads call
+ IndexWriter commit() at the same time. (Mike McCandless)
+
======================= Release 2.4.0 2008-10-06 =======================
Changes in backwards compatibility policy
Modified: lucene/java/branches/lucene_2_4/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_4/src/java/org/apache/lucene/index/IndexWriter.java?rev=747328&r1=747327&r2=747328&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_4/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/java/branches/lucene_2_4/src/java/org/apache/lucene/index/IndexWriter.java Tue Feb 24 10:40:19 2009
@@ -3368,20 +3368,6 @@
finishCommit();
}
- private boolean committing;
-
- synchronized private void waitForCommit() {
- // Only allow a single thread to do the commit, at a time:
- while(committing)
- doWait();
- committing = true;
- }
-
- synchronized private void doneCommit() {
- committing = false;
- notifyAll();
- }
-
/**
* <p>Commits all pending updates (added & deleted
* documents) to the index, and syncs all referenced index
@@ -3411,22 +3397,17 @@
ensureOpen();
- // Only let one thread do the prepare/finish at a time
- waitForCommit();
-
- try {
+ if (infoStream != null)
message("commit: start");
- if (autoCommit || pendingCommit == null) {
+ if (autoCommit || pendingCommit == null) {
+ if (infoStream != null)
message("commit: now prepare");
- prepareCommit(true);
- } else
- message("commit: already prepared");
+ prepareCommit(true);
+ } else if (infoStream != null)
+ message("commit: already prepared");
- finishCommit();
- } finally {
- doneCommit();
- }
+ finishCommit();
}
private synchronized final void finishCommit() throws CorruptIndexException, IOException {
@@ -3479,8 +3460,6 @@
flushCount++;
- // Make sure no threads are actively adding a document
-
flushDeletes |= docWriter.deletesFull();
// When autoCommit=true we must always flush deletes
@@ -3489,6 +3468,7 @@
// from an updateDocument call
flushDeletes |= autoCommit;
+ // Make sure no threads are actively adding a document.
// Returns true if docWriter is currently aborting, in
// which case we skip flushing this segment
if (docWriter.pauseAllThreads()) {
@@ -4635,44 +4615,50 @@
// since I first started syncing my version, I can
// safely skip saving myself since I've been
// superseded:
- if (myChangeCount > lastCommitChangeCount && (pendingCommit == null || myChangeCount > pendingCommitChangeCount)) {
- // Wait now for any current pending commit to complete:
- while(pendingCommit != null) {
- message("wait for existing pendingCommit to finish...");
- doWait();
- }
+ while(true) {
+ if (myChangeCount <= lastCommitChangeCount) {
+ if (infoStream != null) {
+ message("sync superseded by newer infos");
+ }
+ break;
+ } else if (pendingCommit == null) {
+ // My turn to commit
- if (segmentInfos.getGeneration() > toSync.getGeneration())
- toSync.updateGeneration(segmentInfos);
+ if (segmentInfos.getGeneration() > toSync.getGeneration())
+ toSync.updateGeneration(segmentInfos);
- boolean success = false;
- try {
-
- // Exception here means nothing is prepared
- // (this method unwinds everything it did on
- // an exception)
+ boolean success = false;
try {
- toSync.prepareCommit(directory);
+
+ // Exception here means nothing is prepared
+ // (this method unwinds everything it did on
+ // an exception)
+ try {
+ toSync.prepareCommit(directory);
+ } finally {
+ // Have our master segmentInfos record the
+ // generations we just prepared. We do this
+ // on error or success so we don't
+ // double-write a segments_N file.
+ segmentInfos.updateGeneration(toSync);
+ }
+
+ assert pendingCommit == null;
+ setPending = true;
+ pendingCommit = toSync;
+ pendingCommitChangeCount = myChangeCount;
+ success = true;
} finally {
- // Have our master segmentInfos record the
- // generations we just prepared. We do this
- // on error or success so we don't
- // double-write a segments_N file.
- segmentInfos.updateGeneration(toSync);
+ if (!success && infoStream != null)
+ message("hit exception committing segments file");
}
-
- assert pendingCommit == null;
- setPending = true;
- pendingCommit = toSync;
- pendingCommitChangeCount = myChangeCount;
- success = true;
- } finally {
- if (!success)
- message("hit exception committing segments file");
+ break;
+ } else {
+ // Must wait for other commit to complete
+ doWait();
}
- } else
- message("sync superseded by newer infos");
+ }
}
message("done all syncs");