From 765eab4008f44bb655b3dbbe4cc625455711536b Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Mon, 20 Dec 2010 10:35:30 +0000 Subject: [PATCH] LUCENE-2820: fix CMS to stop its threads without deadlocking! git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1051041 13f79535-47bb-0310-9956-ffa450edef68 --- .../index/ConcurrentMergeScheduler.java | 96 ++++++++++++------- .../index/TestIndexWriterExceptions.java | 4 + .../lucene/store/MockDirectoryWrapper.java | 18 ++-- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java b/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java index 56369b92727..b33aa6c1098 100644 --- a/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java +++ b/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java @@ -65,7 +65,6 @@ public class ConcurrentMergeScheduler extends MergeScheduler { protected Directory dir; - private boolean closed; protected IndexWriter writer; protected int mergeThreadCount; @@ -147,18 +146,37 @@ public class ConcurrentMergeScheduler extends MergeScheduler { * pause & unpause threads. */ protected synchronized void updateMergeThreads() { - CollectionUtil.mergeSort(mergeThreads, compareByMergeDocCount); - - final int count = mergeThreads.size(); - int pri = mergeThreadPriority; - for(int i=0;i activeMerges = new ArrayList(); + + int threadIdx = 0; + while (threadIdx < mergeThreads.size()) { + final MergeThread mergeThread = mergeThreads.get(threadIdx); + if (!mergeThread.isAlive()) { + // Prune any dead threads + mergeThreads.remove(threadIdx); continue; } + if (mergeThread.getCurrentMerge() != null) { + activeMerges.add(mergeThread); + } + threadIdx++; + } + + CollectionUtil.mergeSort(activeMerges, compareByMergeDocCount); + + int pri = mergeThreadPriority; + final int activeMergeCount = activeMerges.size(); + for (threadIdx=0;threadIdx 0) { - if (verbose()) - message("now wait for threads; currently " + mergeThreads.size() + " still running"); - final int count = mergeThreads.size(); - if (verbose()) { - for(int i=0;i 0.0) { int number = Math.abs(randomState.nextInt() % 1000); if (number < randomIOExceptionRate*1000) { + if (LuceneTestCase.VERBOSE) { + System.out.println(Thread.currentThread().getName() + ": MockDirectoryWrapper: now throw random exception"); + new Throwable().printStackTrace(System.out); + } throw new IOException("a random IOException"); } }