You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2012/01/22 06:14:46 UTC

svn commit: r1234451 - in /lucene/dev/trunk: ./ dev-tools/idea/lucene/contrib/ lucene/ lucene/contrib/ lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/ lucene/src/java/org/apache/lucene/codecs/lucene3x/ modules/analysis/kuromoji...

Author: shaie
Date: Sun Jan 22 05:14:45 2012
New Revision: 1234451

URL: http://svn.apache.org/viewvc?rev=1234451&view=rev
Log:
LUCENE-3703: Calling DirectoryTaxonomyReader.refresh() could mess up reference counting

Modified:
    lucene/dev/trunk/   (props changed)
    lucene/dev/trunk/dev-tools/idea/lucene/contrib/   (props changed)
    lucene/dev/trunk/lucene/   (props changed)
    lucene/dev/trunk/lucene/contrib/CHANGES.txt   (props changed)
    lucene/dev/trunk/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java   (props changed)
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/codecs/lucene3x/TermInfosReaderIndex.java   (props changed)
    lucene/dev/trunk/modules/analysis/kuromoji/   (props changed)
    lucene/dev/trunk/modules/benchmark/   (props changed)
    lucene/dev/trunk/modules/facet/   (props changed)
    lucene/dev/trunk/modules/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
    lucene/dev/trunk/modules/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java
    lucene/dev/trunk/modules/queryparser/src/test/org/apache/lucene/queryparser/xml/builders/TestNumericRangeFilterBuilder.java   (props changed)
    lucene/dev/trunk/solr/   (props changed)
    lucene/dev/trunk/solr/CHANGES.txt   (props changed)
    lucene/dev/trunk/solr/LICENSE.txt   (props changed)
    lucene/dev/trunk/solr/NOTICE.txt   (props changed)
    lucene/dev/trunk/solr/README.txt   (props changed)
    lucene/dev/trunk/solr/build.xml   (props changed)
    lucene/dev/trunk/solr/client/   (props changed)
    lucene/dev/trunk/solr/common-build.xml   (props changed)
    lucene/dev/trunk/solr/contrib/   (props changed)
    lucene/dev/trunk/solr/contrib/clustering/src/test-files/   (props changed)
    lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/   (props changed)
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/   (props changed)
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test-files/   (props changed)
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/   (props changed)
    lucene/dev/trunk/solr/contrib/uima/src/java/   (props changed)
    lucene/dev/trunk/solr/contrib/uima/src/test-files/   (props changed)
    lucene/dev/trunk/solr/core/   (props changed)
    lucene/dev/trunk/solr/core/src/java/   (props changed)
    lucene/dev/trunk/solr/core/src/test/   (props changed)
    lucene/dev/trunk/solr/dev-tools/   (props changed)
    lucene/dev/trunk/solr/example/   (props changed)
    lucene/dev/trunk/solr/lib/   (props changed)
    lucene/dev/trunk/solr/scripts/   (props changed)
    lucene/dev/trunk/solr/site/   (props changed)
    lucene/dev/trunk/solr/site-src/   (props changed)
    lucene/dev/trunk/solr/solrj/   (props changed)
    lucene/dev/trunk/solr/solrj/src/java/   (props changed)
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/   (props changed)
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/   (props changed)
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/common/   (props changed)
    lucene/dev/trunk/solr/test-framework/   (props changed)
    lucene/dev/trunk/solr/testlogging.properties   (props changed)
    lucene/dev/trunk/solr/webapp/   (props changed)

Modified: lucene/dev/trunk/modules/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/modules/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java?rev=1234451&r1=1234450&r2=1234451&view=diff
==============================================================================
--- lucene/dev/trunk/modules/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java (original)
+++ lucene/dev/trunk/modules/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java Sun Jan 22 05:14:45 2012
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.logging.Level;
@@ -100,6 +101,9 @@ public class DirectoryTaxonomyReader imp
 
   private volatile boolean closed = false;
   
+  // set refCount to 1 at start
+  private final AtomicInteger refCount = new AtomicInteger(1);
+  
   /**
    * Open for reading a taxonomy stored in a given {@link Directory}.
    * @param directory
@@ -130,7 +134,7 @@ public class DirectoryTaxonomyReader imp
    * @throws AlreadyClosedException if this IndexReader is closed
    */
   protected final void ensureOpen() throws AlreadyClosedException {
-    if (indexReader.getRefCount() <= 0) {
+    if (getRefCount() <= 0) {
       throw new AlreadyClosedException("this TaxonomyReader is closed");
     }
   }
@@ -415,8 +419,12 @@ public class DirectoryTaxonomyReader imp
 
   public void close() throws IOException {
     if (!closed) {
-      decRef();
-      closed = true;
+      synchronized (this) {
+        if (!closed) {
+          decRef();
+          closed = true;
+        }
+      }
     }
   }
   
@@ -555,27 +563,31 @@ public class DirectoryTaxonomyReader imp
   }
 
   /**
-   * Expert: decreases the refCount of this TaxonomyReader instance. 
-   * If the refCount drops to 0, then pending changes (if any) are 
-   * committed to the taxonomy index and this reader is closed. 
-   * @throws IOException 
+   * Expert: decreases the refCount of this TaxonomyReader instance. If the
+   * refCount drops to 0, then this reader is closed.
    */
   public void decRef() throws IOException {
     ensureOpen();
-    if (indexReader.getRefCount() == 1) {
-      // Do not decRef the indexReader - doClose does it by calling reader.close()
-      doClose();
-    } else {
-      indexReader.decRef();
+    final int rc = refCount.decrementAndGet();
+    if (rc == 0) {
+      boolean success = false;
+      try {
+        doClose();
+        success = true;
+      } finally {
+        if (!success) {
+          // Put reference back on failure
+          refCount.incrementAndGet();
+        }
+      }
+    } else if (rc < 0) {
+      throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement");
     }
   }
   
-  /**
-   * Expert: returns the current refCount for this taxonomy reader
-   */
+  /** Expert: returns the current refCount for this taxonomy reader */
   public int getRefCount() {
-    ensureOpen();
-    return this.indexReader.getRefCount();
+    return refCount.get();
   }
   
   /**
@@ -587,6 +599,6 @@ public class DirectoryTaxonomyReader imp
    */
   public void incRef() {
     ensureOpen();
-    this.indexReader.incRef();
+    refCount.incrementAndGet();
   }
 }

Modified: lucene/dev/trunk/modules/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/modules/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java?rev=1234451&r1=1234450&r2=1234451&view=diff
==============================================================================
--- lucene/dev/trunk/modules/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java (original)
+++ lucene/dev/trunk/modules/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java Sun Jan 22 05:14:45 2012
@@ -11,6 +11,7 @@ import org.apache.lucene.facet.taxonomy.
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.junit.Test;
@@ -178,4 +179,28 @@ public class TestDirectoryTaxonomyReader
     }
   }
   
+  @Test
+  public void testRefreshAndRefCount() throws Exception {
+    Directory dir = new RAMDirectory(); // no need for random directories here
+
+    DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(dir);
+    taxoWriter.addCategory(new CategoryPath("a"));
+    taxoWriter.commit();
+
+    DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(dir);
+    assertEquals("wrong refCount", 1, taxoReader.getRefCount());
+
+    taxoReader.incRef();
+    assertEquals("wrong refCount", 2, taxoReader.getRefCount());
+
+    taxoWriter.addCategory(new CategoryPath("a", "b"));
+    taxoWriter.commit();
+    taxoReader.refresh();
+    assertEquals("wrong refCount", 2, taxoReader.getRefCount());
+
+    taxoWriter.close();
+    taxoReader.close();
+    dir.close();
+  }
+
 }