Index: src/test/org/apache/lucene/index/TestIndexWriter.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriter.java (revision 836166) +++ src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) @@ -4367,27 +4367,62 @@ private class IndexerThreadInterrupt extends Thread { volatile boolean failed; volatile boolean finish; + + boolean allowInterrupt = false; + @Override public void run() { RAMDirectory dir = new RAMDirectory(); IndexWriter w = null; + boolean first = true; while(!finish) { try { - //IndexWriter.unlock(dir); - w = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED); - ((ConcurrentMergeScheduler) w.getMergeScheduler()).setSuppressExceptions(); - //w.setInfoStream(System.out); - w.setMaxBufferedDocs(2); - w.setMergeFactor(2); - Document doc = new Document(); - doc.add(new Field("field", "some text contents", Field.Store.YES, Field.Index.ANALYZED)); - for(int i=0;i<100;i++) { - w.addDocument(doc); - w.commit(); + + while(true) { + if (w != null) { + w.close(); + } + w = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED); + + //((ConcurrentMergeScheduler) w.getMergeScheduler()).setSuppressExceptions(); + if (!first && !allowInterrupt) { + // tell main thread it can interrupt us any time, + // starting now + allowInterrupt = true; + } + + w.setMaxBufferedDocs(2); + w.setMergeFactor(2); + Document doc = new Document(); + doc.add(new Field("field", "some text contents", Field.Store.YES, Field.Index.ANALYZED)); + for(int i=0;i<100;i++) { + w.addDocument(doc); + w.commit(); + } + w.close(); + _TestUtil.checkIndex(dir); + IndexReader.open(dir, true).close(); + + if (first && !allowInterrupt) { + // Strangely, if we interrupt a thread before + // all classes are loaded, the class loader + // seems to do scary things with the interrupt + // status. In java 1.5, it'll throw an + // incorrect ClassNotFoundException. In java + // 1.6, it'll silently clear the interrupt. + // So, on first iteration through here we + // don't open ourselves up for interrupts + // until we've done the above loop. + allowInterrupt = true; + first = false; + } } } catch (ThreadInterruptedException re) { Throwable e = re.getCause(); assertTrue(e instanceof InterruptedException); + if (finish) { + break; + } // Make sure IW cleared the interrupted bit if (interrupted()) { @@ -4396,26 +4431,12 @@ failed = true; break; } + } catch (Throwable t) { System.out.println("FAILED; unexpected exception"); t.printStackTrace(System.out); failed = true; break; - } finally { - try { - // Clear interrupt if pending - synchronized(this) { - interrupted(); - if (w != null) { - w.close(); - } - } - } catch (Throwable t) { - System.out.println("FAILED; unexpected exception during close"); - t.printStackTrace(System.out); - failed = true; - break; - } } } @@ -4444,16 +4465,24 @@ IndexerThreadInterrupt t = new IndexerThreadInterrupt(); t.setDaemon(true); t.start(); - for(int i=0;i<100;i++) { + + // issue 100 interrupts to child thread + int i = 0; + while(i < 100) { Thread.sleep(1); - synchronized(t) { + + if (t.allowInterrupt) { + i++; + t.allowInterrupt = false; t.interrupt(); } + if (!t.isAlive()) { + break; + } } + t.allowInterrupt = false; t.finish = true; - synchronized(t) { - t.interrupt(); - } + t.interrupt(); t.join(); assertFalse(t.failed); }