From bd6f01251100eac140f2519eb1a716d3ce5c4857 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Fri, 17 Nov 2006 22:34:17 +0000 Subject: [PATCH] make sure to release write lock in IndexWriter if we hit IOException during construction git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@476345 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 5 ++ .../org/apache/lucene/index/IndexWriter.java | 27 +++++--- .../index/TestIndexWriterLockRelease.java | 67 +++++++++++++++++++ 3 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/test/org/apache/lucene/index/TestIndexWriterLockRelease.java diff --git a/CHANGES.txt b/CHANGES.txt index 8cc78cfcee5..973e2d053b0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -171,6 +171,11 @@ Bug fixes 20. LUCENE-706: Updated fileformats.xml|html concerning the docdelta value in the frequency file. (Johan Stuyts, Doron Cohen via Grant Ingersoll) +21. LUCENE-715: Fixed private constructor in IndexWriter.java to + properly release the acquired write lock if there is an + IOException after acquiring the write lock but before finishing + instantiation (Matthew Bogosian via Mike McCandless) + Optimizations 1. LUCENE-586: TermDocs.skipTo() is now more efficient for diff --git a/src/java/org/apache/lucene/index/IndexWriter.java b/src/java/org/apache/lucene/index/IndexWriter.java index b128de65868..9533aebb6f6 100644 --- a/src/java/org/apache/lucene/index/IndexWriter.java +++ b/src/java/org/apache/lucene/index/IndexWriter.java @@ -259,16 +259,23 @@ public class IndexWriter { throw new IOException("Index locked for write: " + writeLock); this.writeLock = writeLock; // save it - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock(IndexWriter.COMMIT_LOCK_NAME), commitLockTimeout) { - public Object doBody() throws IOException { - if (create) - segmentInfos.write(directory); - else - segmentInfos.read(directory); - return null; - } - }.run(); + try { + synchronized (directory) { // in- & inter-process sync + new Lock.With(directory.makeLock(IndexWriter.COMMIT_LOCK_NAME), commitLockTimeout) { + public Object doBody() throws IOException { + if (create) + segmentInfos.write(directory); + else + segmentInfos.read(directory); + return null; + } + }.run(); + } + } catch (IOException e) { + // the doBody method failed + this.writeLock.release(); + this.writeLock = null; + throw e; } } diff --git a/src/test/org/apache/lucene/index/TestIndexWriterLockRelease.java b/src/test/org/apache/lucene/index/TestIndexWriterLockRelease.java new file mode 100644 index 00000000000..85e89985546 --- /dev/null +++ b/src/test/org/apache/lucene/index/TestIndexWriterLockRelease.java @@ -0,0 +1,67 @@ +package org.apache.lucene.index; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import junit.framework.TestCase; +import org.apache.lucene.index.IndexModifier; + +/** + * This tests the patch for issue #LUCENE-715 (IndexWriter does not + * release its write lock when trying to open an index which does not yet + * exist). + * + * @author mbogosian + * @version $Id$ + */ + +public class TestIndexWriterLockRelease extends TestCase { + private java.io.File __test_dir; + + public void setUp() throws IOException { + if (this.__test_dir == null) { + String tmp_dir = System.getProperty("java.io.tmpdir", "tmp"); + this.__test_dir = new File(tmp_dir, "testIndexWriter"); + + if (this.__test_dir.exists()) { + throw new IOException("test directory \"" + this.__test_dir.getPath() + "\" already exists (please remove by hand)"); + } + + if (!this.__test_dir.mkdirs() + && !this.__test_dir.isDirectory()) { + throw new IOException("unable to create test directory \"" + this.__test_dir.getPath() + "\""); + } + } + } + + public void tearDown() throws IOException { + if (this.__test_dir != null) { + File[] files = this.__test_dir.listFiles(); + + for (int i = 0; + i < files.length; + ++i) { + if (!files[i].delete()) { + throw new IOException("unable to remove file in test directory \"" + this.__test_dir.getPath() + "\" (please remove by hand)"); + } + } + + if (!this.__test_dir.delete()) { + throw new IOException("unable to remove test directory \"" + this.__test_dir.getPath() + "\" (please remove by hand)"); + } + } + } + + public void testIndexWriterLockRelease() throws IOException { + IndexModifier im; + + try { + im = new IndexModifier(this.__test_dir, new org.apache.lucene.analysis.standard.StandardAnalyzer(), false); + } catch (FileNotFoundException e) { + try { + im = new IndexModifier(this.__test_dir, new org.apache.lucene.analysis.standard.StandardAnalyzer(), false); + } catch (FileNotFoundException e1) { + } + } + } +}