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 02:30:35 UTC
svn commit: r747251 -
/lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java
Author: mikemccand
Date: Tue Feb 24 01:30:35 2009
New Revision: 747251
URL: http://svn.apache.org/viewvc?rev=747251&view=rev
Log:
LUCENE-1547: fix rare thread hazard in IndexWriter.commit()
Modified:
lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java
Modified: lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java?rev=747251&r1=747250&r2=747251&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java Tue Feb 24 01:30:35 2009
@@ -3610,20 +3610,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
@@ -3670,24 +3656,17 @@
ensureOpen();
- // Only let one thread do the prepare/finish at a time
- waitForCommit();
+ if (infoStream != null)
+ message("commit: start");
- try {
+ if (autoCommit || pendingCommit == null) {
if (infoStream != null)
- message("commit: start");
-
- if (autoCommit || pendingCommit == null) {
- if (infoStream != null)
- message("commit: now prepare");
- prepareCommit(commitUserData, true);
- } else if (infoStream != null)
- message("commit: already prepared");
+ message("commit: now prepare");
+ prepareCommit(commitUserData, true);
+ } else if (infoStream != null)
+ message("commit: already prepared");
- finishCommit();
- } finally {
- doneCommit();
- }
+ finishCommit();
}
private synchronized final void finishCommit() throws CorruptIndexException, IOException {
@@ -3745,8 +3724,6 @@
flushCount++;
- // Make sure no threads are actively adding a document
-
flushDeletes |= docWriter.deletesFull();
// When autoCommit=true we must always flush deletes
@@ -3755,6 +3732,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()) {
@@ -4891,45 +4869,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) {
- if (infoStream != null)
- message("wait for existing pendingCommit to finish...");
- doWait();
- }
-
- if (segmentInfos.getGeneration() > toSync.getGeneration())
- toSync.updateGeneration(segmentInfos);
+ while(true) {
+ if (myChangeCount <= lastCommitChangeCount) {
+ if (infoStream != null) {
+ message("sync superseded by newer infos");
+ }
+ break;
+ } else if (pendingCommit == null) {
+ // My turn to commit
- boolean success = false;
- try {
+ if (segmentInfos.getGeneration() > toSync.getGeneration())
+ toSync.updateGeneration(segmentInfos);
- // 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 && infoStream != null)
- message("hit exception committing segments file");
+ break;
+ } else {
+ // Must wait for other commit to complete
+ doWait();
}
- } else if (infoStream != null)
- message("sync superseded by newer infos");
+ }
}
if (infoStream != null)