You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2021/10/17 15:55:45 UTC
[lucenenet] branch master updated (d7a68e4 -> 3dcffb2)
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git.
from d7a68e4 Lucene.Net.Index.IndexWriter: Removed call to ThreadJob.Interrupted() which internally calls Thread.Sleep(0) which was causing performance issues and deadlocks during IndexWriter.Dispose()
new 3144ba7 Removed [Deadlock] attribute from tests that were deadlocking due to extra Thread.Sleep(0) call in IndexWriter.Dispose().
new b1e0eec SWEEP: Added Lucene.Net.Util.ThreadInterruptedException and re-throw it in all of the places that Lucene does.
new dd89a4f Lucene.Net.Support.Threading: Created UninterruptableMonitor class to handle entering locks without throwing System.Threading.ThreadInterruptedException (which is what happens in Java)
new 19cb0c1 SWEEP: Lucene.Net: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
new 152ffe6 SWEEP: Lucene.Net.TestFramework: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
new 7c357e7 SWEEP: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
new b5ce511 Lucene.Net.Index.DocumentsWriter::UnlockAllAfterAbortAll() Added missing when clause on catch block
new 3dcffb2 Lucene.Net.Tests.Index.TestIndexWriter: Removed [AwaitsFix] attribute from TestThreadInterruptDeadlock() and TestTwoThreadsInterruptDeadlock(), since they now are passing
The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../Analysis/Th/ThaiTokenizer.cs | 71 +-
.../Analysis/Util/AnalysisSPILoader.cs | 8 +-
.../Analysis/Util/BufferedCharFilter.cs | 43 +-
.../Analysis/Icu/Segmentation/ICUTokenizer.cs | 26 +-
.../Tools/NLPChunkerOp.cs | 8 +-
.../Tools/NLPNERTaggerOp.cs | 8 +-
.../Tools/NLPPOSTaggerOp.cs | 8 +-
.../Tools/NLPSentenceDetectorOp.cs | 8 +-
.../Tools/NLPTokenizerOp.cs | 8 +-
.../Hhmm/BigramDictionary.cs | 8 +-
.../Hhmm/WordDictionary.cs | 8 +-
src/Lucene.Net.Benchmark/ByTask/Benchmark.cs | 8 +-
.../ByTask/Feeds/AbstractQueryMaker.cs | 8 +-
.../ByTask/Feeds/ContentItemsSource.cs | 15 +-
.../ByTask/Feeds/DirContentSource.cs | 15 +-
.../ByTask/Feeds/EnwikiContentSource.cs | 79 ++-
.../ByTask/Feeds/LineDocSource.cs | 8 +-
.../ByTask/Feeds/LongToEnglishContentSource.cs | 17 +-
.../ByTask/Feeds/LongToEnglishQueryMaker.cs | 15 +-
.../ByTask/Feeds/ReutersContentSource.cs | 15 +-
.../ByTask/Feeds/SingleDocSource.cs | 18 +-
.../ByTask/Feeds/TrecContentSource.cs | 15 +-
src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs | 57 +-
src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs | 22 +-
.../ByTask/Tasks/NearRealtimeReaderTask.cs | 1 +
.../ByTask/Tasks/TaskSequence.cs | 1 +
src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs | 3 +-
.../ByTask/Tasks/WriteLineDocTask.cs | 15 +-
.../Memory/DirectDocValuesProducer.cs | 36 +-
.../Memory/MemoryDocValuesProducer.cs | 36 +-
.../SimpleText/SimpleTextFieldsReader.cs | 8 +-
src/Lucene.Net.Facet/FacetsConfig.cs | 36 +-
.../Taxonomy/CachedOrdinalsReader.cs | 15 +-
.../Taxonomy/Directory/DirectoryTaxonomyWriter.cs | 92 ++-
src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs | 8 +-
.../WriterCache/Cl2oTaxonomyWriterCache.cs | 8 +-
.../Taxonomy/WriterCache/LruTaxonomyWriterCache.cs | 36 +-
.../Taxonomy/WriterCache/NameIntCacheLRU.cs | 8 +-
.../AbstractFirstPassGroupingCollector.cs | 15 +-
src/Lucene.Net.Misc/Document/LazyDocument.cs | 15 +-
.../Surround/Query/BasicQueryFactory.cs | 8 +-
.../Xml/Builders/CachedFilterBuilder.cs | 8 +-
.../Xml/Builders/UserInputQueryBuilder.cs | 8 +-
src/Lucene.Net.Replicator/LocalReplicator.cs | 50 +-
src/Lucene.Net.Replicator/ReplicationClient.cs | 27 +-
src/Lucene.Net.Suggest/Spell/SpellChecker.cs | 45 +-
.../Suggest/Analyzing/AnalyzingInfixSuggester.cs | 8 +-
.../Suggest/Fst/FSTCompletionLookup.cs | 15 +-
src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs | 15 +-
.../Analysis/BaseTokenStreamTestCase.cs | 1 +
.../Analysis/MockAnalyzer.cs | 8 +-
.../Codecs/RAMOnly/RAMOnlyPostingsFormat.cs | 17 +-
.../Index/BaseDocValuesFormatTestCase.cs | 1 +
.../Index/BaseMergePolicyTestCase.cs | 8 +-
.../Index/BasePostingsFormatTestCase.cs | 7 +-
.../Index/ThreadedIndexingAndSearchingTestCase.cs | 1 +
.../Search/RandomSimilarityProvider.cs | 15 +-
.../Search/SearchEquivalenceTestBase.cs | 7 +-
.../Store/MockDirectoryWrapper.cs | 211 +++++-
.../Store/SlowClosingMockIndexInputWrapper.cs | 9 +-
.../Store/SlowOpeningMockIndexInputWrapper.cs | 5 +-
src/Lucene.Net.TestFramework/Util/LineFileDocs.cs | 36 +-
.../Util/LuceneTestCase.cs | 28 +-
src/Lucene.Net.TestFramework/Util/TestUtil.cs | 1 +
.../Util/ThrottledIndexOutput.cs | 14 +-
.../Analysis/Th/TestThaiAnalyzer.cs | 1 +
.../Analysis/Icu/Segmentation/TestICUTokenizer.cs | 1 +
.../ByTask/Tasks/CountingSearchTestTask.cs | 8 +-
.../SimpleText/TestSimpleTextStoredFieldsFormat.cs | 1 -
src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs | 27 +-
.../Taxonomy/TestSearcherTaxonomyManager.cs | 1 +
.../Taxonomy/TestTaxonomyCombined.cs | 2 +
.../IndexAndTaxonomyReplicationClientTest.cs | 11 +-
.../IndexReplicationClientTest.cs | 11 +-
.../LocalReplicatorTest.cs | 1 +
.../Spell/TestSpellChecker.cs | 1 +
.../Analyzing/AnalyzingInfixSuggesterTest.cs | 1 +
src/Lucene.Net.Tests/Index/TestAddIndexes.cs | 23 +-
src/Lucene.Net.Tests/Index/TestBagOfPositions.cs | 1 +
src/Lucene.Net.Tests/Index/TestBagOfPostings.cs | 1 +
.../Index/TestConcurrentMergeScheduler.cs | 1 +
src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs | 1 +
src/Lucene.Net.Tests/Index/TestDirectoryReader.cs | 1 +
.../Index/TestDirectoryReaderReopen.cs | 35 +-
.../Index/TestDocumentsWriterDeleteQueue.cs | 13 +-
.../Index/TestDocumentsWriterStallControl.cs | 8 +-
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 71 +-
.../Index/TestIndexWriterExceptions.cs | 9 +-
.../Index/TestIndexWriterMerging.cs | 8 +-
.../Index/TestIndexWriterNRTIsCurrent.cs | 1 +
.../Index/TestIndexWriterOnJRECrash.cs | 1 +
.../Index/TestIndexWriterReader.cs | 23 +-
.../Index/TestIndexWriterWithThreads.cs | 11 +-
.../Index/TestNRTReaderWithThreads.cs | 2 +-
src/Lucene.Net.Tests/Index/TestNeverDelete.cs | 1 +
src/Lucene.Net.Tests/Index/TestPayloads.cs | 22 +-
.../Index/TestSnapshotDeletionPolicy.cs | 12 +-
src/Lucene.Net.Tests/Index/TestStressIndexing2.cs | 22 +-
src/Lucene.Net.Tests/Index/TestStressNRT.cs | 29 +-
src/Lucene.Net.Tests/Index/TestTransactions.cs | 15 +-
.../Search/TestControlledRealTimeReopenThread.cs | 22 +-
.../Search/TestMultiThreadTermVectors.cs | 1 +
src/Lucene.Net.Tests/Search/TestSearcherManager.cs | 15 +-
.../Search/TestTimeLimitingCollector.cs | 20 +-
src/Lucene.Net.Tests/Store/TestLockFactory.cs | 1 +
.../ExceptionHandling/TestExceptionExtensions.cs | 2 +-
.../Threading/TestUninterruptableMonitor.cs | 313 +++++++++
src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs | 1 +
src/Lucene.Net.Tests/Util/TestSetOnce.cs | 1 +
src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs | 8 +-
.../Codecs/Lucene3x/Lucene3xNormsProducer.cs | 15 +-
.../Codecs/Lucene40/Lucene40DocValuesReader.cs | 22 +-
.../Codecs/Lucene42/Lucene42DocValuesProducer.cs | 29 +-
.../Codecs/Lucene45/Lucene45DocValuesProducer.cs | 22 +-
src/Lucene.Net/Index/BufferedUpdatesStream.cs | 57 +-
src/Lucene.Net/Index/ConcurrentMergeScheduler.cs | 130 +++-
src/Lucene.Net/Index/DocumentsWriter.cs | 68 +-
.../Index/DocumentsWriterFlushControl.cs | 171 ++++-
src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs | 59 +-
.../Index/DocumentsWriterPerThreadPool.cs | 40 +-
.../Index/DocumentsWriterStallControl.cs | 62 +-
src/Lucene.Net/Index/FieldInfos.cs | 36 +-
src/Lucene.Net/Index/FlushPolicy.cs | 8 +-
src/Lucene.Net/Index/IndexFileDeleter.cs | 5 +-
src/Lucene.Net/Index/IndexReader.cs | 32 +-
src/Lucene.Net/Index/IndexWriter.cs | 773 +++++++++++++++++----
src/Lucene.Net/Index/MergePolicy.cs | 56 +-
src/Lucene.Net/Index/MultiReader.cs | 10 +-
src/Lucene.Net/Index/ParallelAtomicReader.cs | 8 +-
src/Lucene.Net/Index/ParallelCompositeReader.cs | 8 +-
.../Index/PersistentSnapshotDeletionPolicy.cs | 43 +-
src/Lucene.Net/Index/ReadersAndUpdates.cs | 127 +++-
src/Lucene.Net/Index/SegmentCoreReaders.cs | 10 +-
src/Lucene.Net/Index/SegmentDocValues.cs | 22 +-
src/Lucene.Net/Index/SerialMergeScheduler.cs | 8 +-
src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs | 17 +-
src/Lucene.Net/Index/SnapshotDeletionPolicy.cs | 71 +-
src/Lucene.Net/Index/StoredFieldsProcessor.cs | 10 +-
src/Lucene.Net/Index/TermsEnum.cs | 10 +-
src/Lucene.Net/Search/CachingWrapperFilter.cs | 10 +-
.../Search/ControlledRealTimeReopenThread.cs | 46 +-
src/Lucene.Net/Search/FieldCacheImpl.cs | 66 +-
src/Lucene.Net/Search/IndexSearcher.cs | 3 +-
src/Lucene.Net/Search/ReferenceManager.cs | 14 +-
src/Lucene.Net/Search/SearcherLifetimeManager.cs | 22 +-
src/Lucene.Net/Search/TimeLimitingCollector.cs | 11 +-
src/Lucene.Net/Store/CompoundFileDirectory.cs | 15 +-
src/Lucene.Net/Store/CompoundFileWriter.cs | 8 +-
src/Lucene.Net/Store/Lock.cs | 13 +-
src/Lucene.Net/Store/LockVerifyServer.cs | 8 +-
src/Lucene.Net/Store/NRTCachingDirectory.cs | 57 +-
src/Lucene.Net/Store/NativeFSLockFactory.cs | 109 ++-
src/Lucene.Net/Store/RAMFile.cs | 43 +-
src/Lucene.Net/Store/RateLimiter.cs | 11 +-
src/Lucene.Net/Store/SimpleFSDirectory.cs | 8 +-
src/Lucene.Net/Store/SingleInstanceLockFactory.cs | 29 +-
src/Lucene.Net/Store/VerifyingLockFactory.cs | 36 +-
.../Support/Codecs/DefaultCodecFactory.cs | 24 +-
.../Codecs/DefaultDocValuesFormatFactory.cs | 24 +-
.../Support/Codecs/DefaultPostingsFormatFactory.cs | 24 +-
src/Lucene.Net/Support/ConcurrentHashSet.cs | 17 +-
src/Lucene.Net/Support/ConcurrentSet.cs | 193 ++++-
.../ExceptionHandling/ExceptionExtensions.cs | 10 +-
src/Lucene.Net/Support/IO/StreamExtensions.cs | 8 +-
.../LimitedConcurrencyLevelTaskScheduler.cs | 30 +-
src/Lucene.Net/Support/Threading/ReentrantLock.cs | 8 +-
.../Support/Threading/UninterruptableMonitor.cs | 167 +++++
src/Lucene.Net/Util/AttributeSource.cs | 8 +-
src/Lucene.Net/Util/Fst/Util.cs | 15 +-
src/Lucene.Net/Util/InfoStream.cs | 15 +-
.../Util/ThreadInterruptedException.cs} | 28 +-
171 files changed, 4395 insertions(+), 757 deletions(-)
create mode 100644 src/Lucene.Net.Tests/Support/Threading/TestUninterruptableMonitor.cs
create mode 100644 src/Lucene.Net/Support/Threading/UninterruptableMonitor.cs
copy src/{Lucene.Net.QueryParser/Xml/ParserException.cs => Lucene.Net/Util/ThreadInterruptedException.cs} (64%)
[lucenenet] 01/08: Removed [Deadlock] attribute from tests that
were deadlocking due to extra Thread.Sleep(0) call in
IndexWriter.Dispose().
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 3144ba76a7866526533ee8b89e5cf26207a18ca6
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Oct 10 06:44:10 2021 +0700
Removed [Deadlock] attribute from tests that were deadlocking due to extra Thread.Sleep(0) call in IndexWriter.Dispose().
---
.../SimpleText/TestSimpleTextStoredFieldsFormat.cs | 1 -
src/Lucene.Net.Tests/Index/TestAddIndexes.cs | 1 -
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 6 ++----
src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs | 1 -
src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs | 1 -
src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs | 1 -
src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs | 1 -
7 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/Lucene.Net.Tests.Codecs/SimpleText/TestSimpleTextStoredFieldsFormat.cs b/src/Lucene.Net.Tests.Codecs/SimpleText/TestSimpleTextStoredFieldsFormat.cs
index 5f44527..2f3a765 100644
--- a/src/Lucene.Net.Tests.Codecs/SimpleText/TestSimpleTextStoredFieldsFormat.cs
+++ b/src/Lucene.Net.Tests.Codecs/SimpleText/TestSimpleTextStoredFieldsFormat.cs
@@ -30,7 +30,6 @@ namespace Lucene.Net.Codecs.SimpleText
}
- [Deadlock][Timeout(600000)]
public override void TestConcurrentReads()
{
base.TestConcurrentReads();
diff --git a/src/Lucene.Net.Tests/Index/TestAddIndexes.cs b/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
index 526d1b9..a44c384 100644
--- a/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
+++ b/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
@@ -972,7 +972,6 @@ namespace Lucene.Net.Index
// LUCENE-1335: test simultaneous addIndexes & close
[Test]
[Slow]
- [Deadlock][Timeout(600000)]
public virtual void TestAddIndexesWithCloseNoWait()
{
const int NUM_COPY = 50;
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
index 22f2baa..05f1b09 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
@@ -1438,8 +1438,7 @@ namespace Lucene.Net.Index
[Test]
[Slow]
- [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails
- [Deadlock][Timeout(900000)] // LUCENENET TODO: this test occasionally deadlocks
+ [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails on .NET Core
public virtual void TestThreadInterruptDeadlock()
{
IndexerThreadInterrupt t = new IndexerThreadInterrupt(this);
@@ -1480,8 +1479,7 @@ namespace Lucene.Net.Index
/// testThreadInterruptDeadlock but with 2 indexer threads </summary>
[Test]
[Slow]
- [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails
- [Deadlock][Timeout(900000)] // LUCENENET TODO: this test occasionally deadlocks
+ [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails on .NET Core
public virtual void TestTwoThreadsInterruptDeadlock()
{
IndexerThreadInterrupt t1 = new IndexerThreadInterrupt(this);
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
index 5d774c3..7481bb2 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
@@ -69,7 +69,6 @@ namespace Lucene.Net.Index
using TokenStream = Lucene.Net.Analysis.TokenStream;
[TestFixture]
- [Deadlock][Timeout(600000)]
public class TestIndexWriterExceptions : LuceneTestCase
{
private class DocCopyIterator : IEnumerable<Document>
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
index da3a07f..b000cf5 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
@@ -52,7 +52,6 @@ namespace Lucene.Net.Index
using TopDocs = Lucene.Net.Search.TopDocs;
[TestFixture]
- [Deadlock][Timeout(600000)]
public class TestIndexWriterReader : LuceneTestCase
{
private readonly int numThreads = TestNightly ? 5 : 3;
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
index 11c2d95..f9b0a71 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
@@ -55,7 +55,6 @@ namespace Lucene.Net.Index
/// </summary>
[SuppressCodecs("Lucene3x")]
[Slow]
- [Deadlock][Timeout(1200000)]
[TestFixture]
public class TestIndexWriterWithThreads : LuceneTestCase
{
diff --git a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
index 183f87e..b07e0fe 100644
--- a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
@@ -39,7 +39,6 @@ namespace Lucene.Net.Index
[Test]
[Slow] // (occasionally)
- [Deadlock][Timeout(600000)]
public virtual void TestIndexing()
{
Directory mainDir = NewDirectory();
[lucenenet] 07/08:
Lucene.Net.Index.DocumentsWriter::UnlockAllAfterAbortAll() Added missing
when clause on catch block
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit b5ce511047d5815165b7f454aa00382f0cf7abd6
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sat Oct 16 20:44:39 2021 +0700
Lucene.Net.Index.DocumentsWriter::UnlockAllAfterAbortAll() Added missing when clause on catch block
---
src/Lucene.Net/Index/DocumentsWriter.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Lucene.Net/Index/DocumentsWriter.cs b/src/Lucene.Net/Index/DocumentsWriter.cs
index a1745bf..61c26a4 100644
--- a/src/Lucene.Net/Index/DocumentsWriter.cs
+++ b/src/Lucene.Net/Index/DocumentsWriter.cs
@@ -406,7 +406,7 @@ namespace Lucene.Net.Index
perThread.Unlock();
}
}
- catch (Exception e)
+ catch (Exception e) when (e.IsThrowable())
{
if (infoStream.IsEnabled("DW"))
{
[lucenenet] 04/08: SWEEP: Lucene.Net: Changed all lock statements
to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent
ThreadInterruptedException from occurring when entering a lock.
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 19cb0c1d806462aad2b6297e0885491062887456
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Thu Oct 14 20:41:49 2021 +0700
SWEEP: Lucene.Net: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
---
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 2 +
src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs | 8 +-
.../Codecs/Lucene3x/Lucene3xNormsProducer.cs | 15 +-
.../Codecs/Lucene40/Lucene40DocValuesReader.cs | 22 +-
.../Codecs/Lucene42/Lucene42DocValuesProducer.cs | 29 +-
.../Codecs/Lucene45/Lucene45DocValuesProducer.cs | 22 +-
src/Lucene.Net/Index/BufferedUpdatesStream.cs | 57 +-
src/Lucene.Net/Index/ConcurrentMergeScheduler.cs | 100 ++-
src/Lucene.Net/Index/DocumentsWriter.cs | 66 +-
.../Index/DocumentsWriterFlushControl.cs | 163 ++++-
src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs | 59 +-
.../Index/DocumentsWriterPerThreadPool.cs | 32 +-
.../Index/DocumentsWriterStallControl.cs | 40 +-
src/Lucene.Net/Index/FieldInfos.cs | 36 +-
src/Lucene.Net/Index/FlushPolicy.cs | 8 +-
src/Lucene.Net/Index/IndexFileDeleter.cs | 5 +-
src/Lucene.Net/Index/IndexReader.cs | 32 +-
src/Lucene.Net/Index/IndexWriter.cs | 756 +++++++++++++++++----
src/Lucene.Net/Index/MergePolicy.cs | 56 +-
src/Lucene.Net/Index/MultiReader.cs | 10 +-
src/Lucene.Net/Index/ParallelAtomicReader.cs | 8 +-
src/Lucene.Net/Index/ParallelCompositeReader.cs | 8 +-
.../Index/PersistentSnapshotDeletionPolicy.cs | 43 +-
src/Lucene.Net/Index/ReadersAndUpdates.cs | 127 +++-
src/Lucene.Net/Index/SegmentCoreReaders.cs | 10 +-
src/Lucene.Net/Index/SegmentDocValues.cs | 22 +-
src/Lucene.Net/Index/SerialMergeScheduler.cs | 8 +-
src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs | 17 +-
src/Lucene.Net/Index/SnapshotDeletionPolicy.cs | 71 +-
src/Lucene.Net/Index/StoredFieldsProcessor.cs | 10 +-
src/Lucene.Net/Index/TermsEnum.cs | 10 +-
src/Lucene.Net/Search/CachingWrapperFilter.cs | 10 +-
.../Search/ControlledRealTimeReopenThread.cs | 26 +-
src/Lucene.Net/Search/FieldCacheImpl.cs | 66 +-
src/Lucene.Net/Search/ReferenceManager.cs | 14 +-
src/Lucene.Net/Search/SearcherLifetimeManager.cs | 22 +-
src/Lucene.Net/Search/TimeLimitingCollector.cs | 1 +
src/Lucene.Net/Store/CompoundFileDirectory.cs | 15 +-
src/Lucene.Net/Store/CompoundFileWriter.cs | 8 +-
src/Lucene.Net/Store/Lock.cs | 3 +-
src/Lucene.Net/Store/LockVerifyServer.cs | 8 +-
src/Lucene.Net/Store/NRTCachingDirectory.cs | 57 +-
src/Lucene.Net/Store/NativeFSLockFactory.cs | 109 ++-
src/Lucene.Net/Store/RAMFile.cs | 43 +-
src/Lucene.Net/Store/RateLimiter.cs | 1 +
src/Lucene.Net/Store/SimpleFSDirectory.cs | 8 +-
src/Lucene.Net/Store/SingleInstanceLockFactory.cs | 29 +-
src/Lucene.Net/Store/VerifyingLockFactory.cs | 36 +-
.../Support/Codecs/DefaultCodecFactory.cs | 24 +-
.../Codecs/DefaultDocValuesFormatFactory.cs | 24 +-
.../Support/Codecs/DefaultPostingsFormatFactory.cs | 24 +-
src/Lucene.Net/Support/ConcurrentHashSet.cs | 17 +-
src/Lucene.Net/Support/ConcurrentSet.cs | 193 +++++-
src/Lucene.Net/Support/IO/StreamExtensions.cs | 8 +-
.../LimitedConcurrencyLevelTaskScheduler.cs | 30 +-
src/Lucene.Net/Support/Threading/ReentrantLock.cs | 8 +-
src/Lucene.Net/Util/AttributeSource.cs | 8 +-
src/Lucene.Net/Util/Fst/Util.cs | 15 +-
src/Lucene.Net/Util/InfoStream.cs | 15 +-
59 files changed, 2267 insertions(+), 407 deletions(-)
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
index ce37594..56ade97 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
@@ -10,6 +10,7 @@ using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Search;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
@@ -1387,6 +1388,7 @@ namespace Lucene.Net.Index
// clear interrupt state:
try
{
+ UninterruptableMonitor.RestoreInterrupt();
Thread.Sleep(0);
}
catch (Exception ie) when (ie.IsInterruptedException())
diff --git a/src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs b/src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs
index 68a210d..215d488 100644
--- a/src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs
+++ b/src/Lucene.Net/Codecs/Lucene3x/Lucene3xFields.cs
@@ -1,6 +1,7 @@
using J2N.Text;
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -176,7 +177,8 @@ namespace Lucene.Net.Codecs.Lucene3x
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Tis != null)
{
@@ -187,6 +189,10 @@ namespace Lucene.Net.Codecs.Lucene3x
return TisNoIndex;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Codecs/Lucene3x/Lucene3xNormsProducer.cs b/src/Lucene.Net/Codecs/Lucene3x/Lucene3xNormsProducer.cs
index b5e4792..08a3359 100644
--- a/src/Lucene.Net/Codecs/Lucene3x/Lucene3xNormsProducer.cs
+++ b/src/Lucene.Net/Codecs/Lucene3x/Lucene3xNormsProducer.cs
@@ -1,6 +1,7 @@
using J2N.Runtime.CompilerServices;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -217,17 +218,23 @@ namespace Lucene.Net.Codecs.Lucene3x
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (instance == null)
{
var bytes = new byte[outerInstance.maxdoc];
// some norms share fds
- lock (file)
+ UninterruptableMonitor.Enter(file);
+ try
{
file.Seek(offset);
file.ReadBytes(bytes, 0, bytes.Length, false);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(file);
+ }
// we are done with this file
if (file != outerInstance.singleNormStream)
{
@@ -239,6 +246,10 @@ namespace Lucene.Net.Codecs.Lucene3x
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Codecs/Lucene40/Lucene40DocValuesReader.cs b/src/Lucene.Net/Codecs/Lucene40/Lucene40DocValuesReader.cs
index 55b1a7a..d43765d 100644
--- a/src/Lucene.Net/Codecs/Lucene40/Lucene40DocValuesReader.cs
+++ b/src/Lucene.Net/Codecs/Lucene40/Lucene40DocValuesReader.cs
@@ -1,5 +1,6 @@
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -74,7 +75,8 @@ namespace Lucene.Net.Codecs.Lucene40
public override NumericDocValues GetNumeric(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!numericInstances.TryGetValue(field.Number, out NumericDocValues instance))
{
@@ -138,6 +140,10 @@ namespace Lucene.Net.Codecs.Lucene40
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -431,7 +437,8 @@ namespace Lucene.Net.Codecs.Lucene40
public override BinaryDocValues GetBinary(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!binaryInstances.TryGetValue(field.Number, out BinaryDocValues instance))
{
@@ -461,6 +468,10 @@ namespace Lucene.Net.Codecs.Lucene40
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private BinaryDocValues LoadBytesFixedStraight(FieldInfo field)
@@ -699,7 +710,8 @@ namespace Lucene.Net.Codecs.Lucene40
public override SortedDocValues GetSorted(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!sortedInstances.TryGetValue(field.Number, out SortedDocValues instance))
{
@@ -747,6 +759,10 @@ namespace Lucene.Net.Codecs.Lucene40
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private SortedDocValues LoadBytesFixedSorted(/*FieldInfo field, // LUCENENET: Never read */ IndexInput data, IndexInput index)
diff --git a/src/Lucene.Net/Codecs/Lucene42/Lucene42DocValuesProducer.cs b/src/Lucene.Net/Codecs/Lucene42/Lucene42DocValuesProducer.cs
index e7e85dd..7a9df8a 100644
--- a/src/Lucene.Net/Codecs/Lucene42/Lucene42DocValuesProducer.cs
+++ b/src/Lucene.Net/Codecs/Lucene42/Lucene42DocValuesProducer.cs
@@ -1,5 +1,6 @@
using J2N.Threading.Atomic;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util.Fst;
using System;
using System.Collections.Generic;
@@ -222,7 +223,8 @@ namespace Lucene.Net.Codecs.Lucene42
public override NumericDocValues GetNumeric(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!numericInstances.TryGetValue(field.Number, out NumericDocValues instance) || instance == null)
{
@@ -231,6 +233,10 @@ namespace Lucene.Net.Codecs.Lucene42
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override long RamBytesUsed() => ramBytesUsed;
@@ -348,7 +354,8 @@ namespace Lucene.Net.Codecs.Lucene42
public override BinaryDocValues GetBinary(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!binaryInstances.TryGetValue(field.Number, out BinaryDocValues instance) || instance == null)
{
@@ -357,6 +364,10 @@ namespace Lucene.Net.Codecs.Lucene42
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private BinaryDocValues LoadBinary(FieldInfo field)
@@ -422,7 +433,8 @@ namespace Lucene.Net.Codecs.Lucene42
{
FSTEntry entry = fsts[field.Number];
FST<long?> instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!fstInstances.TryGetValue(field.Number, out instance) || instance == null)
{
@@ -432,6 +444,10 @@ namespace Lucene.Net.Codecs.Lucene42
fstInstances[field.Number] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
var docToOrd = GetNumeric(field);
var fst = instance;
@@ -533,7 +549,8 @@ namespace Lucene.Net.Codecs.Lucene42
return DocValues.EMPTY_SORTED_SET; // empty FST!
}
FST<long?> instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!fstInstances.TryGetValue(field.Number, out instance) || instance == null)
{
@@ -543,6 +560,10 @@ namespace Lucene.Net.Codecs.Lucene42
fstInstances[field.Number] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
BinaryDocValues docToOrds = GetBinary(field);
FST<long?> fst = instance;
diff --git a/src/Lucene.Net/Codecs/Lucene45/Lucene45DocValuesProducer.cs b/src/Lucene.Net/Codecs/Lucene45/Lucene45DocValuesProducer.cs
index f0f945d..36b9d6a 100644
--- a/src/Lucene.Net/Codecs/Lucene45/Lucene45DocValuesProducer.cs
+++ b/src/Lucene.Net/Codecs/Lucene45/Lucene45DocValuesProducer.cs
@@ -2,6 +2,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -507,7 +508,8 @@ namespace Lucene.Net.Codecs.Lucene45
protected virtual MonotonicBlockPackedReader GetAddressInstance(IndexInput data, FieldInfo field, BinaryEntry bytes)
{
MonotonicBlockPackedReader addresses;
- lock (addressInstances)
+ UninterruptableMonitor.Enter(addressInstances);
+ try
{
if (!addressInstances.TryGetValue(field.Number, out MonotonicBlockPackedReader addrInstance) || addrInstance == null)
{
@@ -518,6 +520,10 @@ namespace Lucene.Net.Codecs.Lucene45
}
addresses = addrInstance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(addressInstances);
+ }
return addresses;
}
@@ -576,7 +582,8 @@ namespace Lucene.Net.Codecs.Lucene45
{
MonotonicBlockPackedReader addresses;
long interval = bytes.AddressInterval;
- lock (addressInstances)
+ UninterruptableMonitor.Enter(addressInstances);
+ try
{
if (!addressInstances.TryGetValue(field.Number, out MonotonicBlockPackedReader addrInstance))
{
@@ -596,6 +603,10 @@ namespace Lucene.Net.Codecs.Lucene45
}
addresses = addrInstance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(addressInstances);
+ }
return addresses;
}
@@ -683,7 +694,8 @@ namespace Lucene.Net.Codecs.Lucene45
protected virtual MonotonicBlockPackedReader GetOrdIndexInstance(IndexInput data, FieldInfo field, NumericEntry entry)
{
MonotonicBlockPackedReader ordIndex;
- lock (ordIndexInstances)
+ UninterruptableMonitor.Enter(ordIndexInstances);
+ try
{
if (!ordIndexInstances.TryGetValue(field.Number, out MonotonicBlockPackedReader ordIndexInstance))
{
@@ -694,6 +706,10 @@ namespace Lucene.Net.Codecs.Lucene45
}
ordIndex = ordIndexInstance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(ordIndexInstances);
+ }
return ordIndex;
}
diff --git a/src/Lucene.Net/Index/BufferedUpdatesStream.cs b/src/Lucene.Net/Index/BufferedUpdatesStream.cs
index 526586b..3139391 100644
--- a/src/Lucene.Net/Index/BufferedUpdatesStream.cs
+++ b/src/Lucene.Net/Index/BufferedUpdatesStream.cs
@@ -1,6 +1,7 @@
using J2N.Text;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -78,7 +79,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual long Push(FrozenBufferedUpdates packet)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
/*
* The insert operation must be atomic. If we let threads increment the gen
@@ -105,17 +107,26 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(CheckDeleteStats());
return packet.DelGen;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void Clear()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
updates.Clear();
nextGen = 1;
numTerms.Value = 0;
bytesUsed.Value = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual bool Any() => bytesUsed != 0;
@@ -169,7 +180,8 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual ApplyDeletesResult ApplyDeletesAndUpdates(IndexWriter.ReaderPool readerPool, IList<SegmentCommitInfo> infos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
@@ -371,14 +383,23 @@ namespace Lucene.Net.Index
return new ApplyDeletesResult(anyNewDeletes, gen, allDeleted);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual long GetNextGen()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return nextGen++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// Lock order IW -> BD
@@ -390,7 +411,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void Prune(SegmentInfos segmentInfos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(CheckDeleteStats());
long minGen = long.MaxValue;
@@ -422,11 +444,16 @@ namespace Lucene.Net.Index
Debugging.Assert(CheckDeleteStats());
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void Prune(int count)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (count > 0)
{
@@ -445,12 +472,17 @@ namespace Lucene.Net.Index
updates.RemoveRange(0, count); // LUCENENET: Checked count parameter for correctness
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// Delete by Term
private long ApplyTermDeletes(IEnumerable<Term> termsIter, ReadersAndUpdates rld, SegmentReader reader)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
long delCount = 0;
Fields fields = reader.Fields;
@@ -535,12 +567,17 @@ namespace Lucene.Net.Index
return delCount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// DocValues updates
private void ApplyDocValuesUpdates<T1>(IEnumerable<T1> updates, ReadersAndUpdates rld, SegmentReader reader, DocValuesFieldUpdates.Container dvUpdatesContainer) where T1 : DocValuesUpdate
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Fields fields = reader.Fields;
if (fields == null)
@@ -627,6 +664,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public class QueryAndLimit
diff --git a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
index 16c3b00..c653b42 100644
--- a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
+++ b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
@@ -1,5 +1,6 @@
using J2N.Threading;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@@ -149,11 +150,16 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
InitMergeThreadPriority();
return mergeThreadPriority;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -167,7 +173,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void SetMergeThreadPriority(int priority)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (priority > (int)ThreadPriority.Highest || priority < (int)ThreadPriority.Lowest)
{
@@ -176,6 +183,10 @@ namespace Lucene.Net.Index
mergeThreadPriority = priority;
UpdateMergeThreads();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -199,7 +210,8 @@ namespace Lucene.Net.Index
/// </summary>
protected virtual void UpdateMergeThreads()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Only look at threads that are alive & not in the
// process of stopping (ie have an active merge):
@@ -269,6 +281,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -295,7 +311,8 @@ namespace Lucene.Net.Index
private void InitMergeThreadPriority()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (mergeThreadPriority == -1)
{
@@ -308,6 +325,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
@@ -325,7 +346,8 @@ namespace Lucene.Net.Index
while (true)
{
MergeThread toSync = null;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (MergeThread t in m_mergeThreads)
{
@@ -336,6 +358,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (toSync != null)
{
try
@@ -372,7 +398,8 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int count = 0;
foreach (MergeThread mt in m_mergeThreads)
@@ -384,15 +411,20 @@ namespace Lucene.Net.Index
}
return count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public override void Merge(IndexWriter writer, MergeTrigger trigger, bool newMergesFound)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(!Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(!UninterruptableMonitor.IsEntered(writer));
this.m_writer = writer;
@@ -436,7 +468,7 @@ namespace Lucene.Net.Index
}
try
{
- Monitor.Wait(this);
+ UninterruptableMonitor.Wait(this);
}
catch (Exception ie) when (ie.IsInterruptedException())
{
@@ -497,6 +529,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -511,7 +547,8 @@ namespace Lucene.Net.Index
/// Create and return a new <see cref="MergeThread"/> </summary>
protected virtual MergeThread GetMergeThread(IndexWriter writer, MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MergeThread thread = new MergeThread(this, writer, merge);
thread.SetThreadPriority((ThreadPriority)mergeThreadPriority);
@@ -519,6 +556,10 @@ namespace Lucene.Net.Index
thread.Name = "Lucene Merge Thread #" + m_mergeThreadCount++;
return thread;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -549,17 +590,27 @@ namespace Lucene.Net.Index
{
set
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
runningMerge = value;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return runningMerge;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -571,7 +622,8 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (done)
{
@@ -586,6 +638,10 @@ namespace Lucene.Net.Index
return startMerge;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -639,9 +695,14 @@ namespace Lucene.Net.Index
// Notify here in case any threads were stalled;
// they will notice that the pending merge has
// been pulled and possibly resume:
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
- Monitor.PulseAll(outerInstance);
+ UninterruptableMonitor.PulseAll(outerInstance);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
}
if (merge != null)
@@ -681,10 +742,15 @@ namespace Lucene.Net.Index
finally
{
done = true;
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
outerInstance.UpdateMergeThreads();
- Monitor.PulseAll(outerInstance);
+ UninterruptableMonitor.PulseAll(outerInstance);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
}
}
}
diff --git a/src/Lucene.Net/Index/DocumentsWriter.cs b/src/Lucene.Net/Index/DocumentsWriter.cs
index 2bbde15..a1745bf 100644
--- a/src/Lucene.Net/Index/DocumentsWriter.cs
+++ b/src/Lucene.Net/Index/DocumentsWriter.cs
@@ -1,5 +1,6 @@
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -146,7 +147,8 @@ namespace Lucene.Net.Index
internal bool DeleteQueries(params Query[] queries)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// TODO why is this synchronized?
DocumentsWriterDeleteQueue deleteQueue = this.deleteQueue;
@@ -154,6 +156,10 @@ namespace Lucene.Net.Index
flushControl.DoOnDelete();
return ApplyAllDeletes(deleteQueue);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// TODO: we could check w/ FreqProxTermsWriter: if the
@@ -161,7 +167,8 @@ namespace Lucene.Net.Index
// per-DWPT map (but still must go into the global map)
internal bool DeleteTerms(params Term[] terms)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// TODO why is this synchronized?
DocumentsWriterDeleteQueue deleteQueue = this.deleteQueue;
@@ -169,28 +176,42 @@ namespace Lucene.Net.Index
flushControl.DoOnDelete();
return ApplyAllDeletes(deleteQueue);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal bool UpdateNumericDocValue(Term term, string field, long? value)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
DocumentsWriterDeleteQueue deleteQueue = this.deleteQueue;
deleteQueue.AddNumericUpdate(new NumericDocValuesUpdate(term, field, value));
flushControl.DoOnDelete();
return ApplyAllDeletes(deleteQueue);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal bool UpdateBinaryDocValue(Term term, string field, BytesRef value)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
DocumentsWriterDeleteQueue deleteQueue = this.deleteQueue;
deleteQueue.AddBinaryUpdate(new BinaryDocValuesUpdate(term, field, value));
flushControl.DoOnDelete();
return ApplyAllDeletes(deleteQueue);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal DocumentsWriterDeleteQueue CurrentDeleteSession => deleteQueue;
@@ -242,9 +263,10 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
internal void Abort(IndexWriter writer)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(!Monitor.IsEntered(writer), "IndexWriter lock should never be hold when aborting");
+ if (Debugging.AssertsEnabled) Debugging.Assert(!UninterruptableMonitor.IsEntered(writer), "IndexWriter lock should never be hold when aborting");
bool success = false;
JCG.HashSet<string> newFilesSet = new JCG.HashSet<string>();
try
@@ -281,11 +303,16 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void LockAndAbortAll(IndexWriter indexWriter)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(indexWriter.HoldsFullFlushLock);
if (infoStream.IsEnabled("DW"))
@@ -323,6 +350,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void AbortThreadState(ThreadState perThread, ISet<string> newFiles)
@@ -356,7 +387,8 @@ namespace Lucene.Net.Index
internal void UnlockAllAfterAbortAll(IndexWriter indexWriter)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(indexWriter.HoldsFullFlushLock);
if (infoStream.IsEnabled("DW"))
@@ -384,6 +416,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal bool AnyChanges()
@@ -708,11 +744,16 @@ namespace Lucene.Net.Index
// for asserts
private bool SetFlushingDeleteQueue(DocumentsWriterDeleteQueue session)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
currentFullFlushDelQueue = session;
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/*
@@ -729,7 +770,8 @@ namespace Lucene.Net.Index
infoStream.Message("DW", "startFullFlush");
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
pendingChangesInCurrentFullFlush = AnyChanges();
flushingDeleteQueue = deleteQueue;
@@ -739,6 +781,10 @@ namespace Lucene.Net.Index
flushControl.MarkForFullFlush(); // swaps the delQueue synced on FlushControl
if (Debugging.AssertsEnabled) Debugging.Assert(SetFlushingDeleteQueue(flushingDeleteQueue));
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (Debugging.AssertsEnabled)
{
Debugging.Assert(currentFullFlushDelQueue != null);
diff --git a/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs b/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
index 124f8b7..f854ab0 100644
--- a/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
@@ -1,6 +1,7 @@
using J2N.Runtime.CompilerServices;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Threading;
@@ -86,10 +87,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return activeBytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -97,10 +103,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return flushBytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -108,10 +119,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return flushBytes + activeBytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -195,7 +211,8 @@ namespace Lucene.Net.Index
internal DocumentsWriterPerThread DoAfterDocument(ThreadState perThread, bool isUpdate)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
try
{
@@ -242,6 +259,10 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(AssertNumDocsSinceStalled(stalled) && AssertMemory());
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool AssertNumDocsSinceStalled(bool stalled)
@@ -266,7 +287,8 @@ namespace Lucene.Net.Index
internal void DoAfterFlush(DocumentsWriterPerThread dwpt)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(flushingWriters.ContainsKey(dwpt));
try
@@ -285,15 +307,19 @@ namespace Lucene.Net.Index
}
finally
{
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool UpdateStallState()
{
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(this));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(this));
long limit = StallLimitBytes;
/*
* we block indexing threads if net byte grows due to slow flushes
@@ -309,13 +335,14 @@ namespace Lucene.Net.Index
public void WaitForFlush()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (flushingWriters.Count != 0)
{
try
{
- Monitor.Wait(this);
+ UninterruptableMonitor.Wait(this);
}
catch (Exception ie) when (ie.IsInterruptedException())
{
@@ -323,6 +350,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -332,7 +363,8 @@ namespace Lucene.Net.Index
/// </summary>
public void SetFlushPending(ThreadState perThread)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(!perThread.flushPending);
if (perThread.dwpt.NumDocsInRAM > 0)
@@ -345,11 +377,16 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(AssertMemory());
} // don't assert on numDocs since we could hit an abort excp. while selecting that dwpt for flushing
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void DoOnAbort(ThreadState state)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
try
{
@@ -370,15 +407,24 @@ namespace Lucene.Net.Index
UpdateStallState();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal DocumentsWriterPerThread TryCheckoutForFlush(ThreadState perThread)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(perThread.IsHeldByCurrentThread); // LUCENENET specific: Since .NET Core doesn't use unfair locking, we need to ensure the current thread has a lock before calling InternalTryCheckoutForFlush.
return perThread.flushPending ? InternalTryCheckOutForFlush(perThread) : null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void CheckoutAndBlock(ThreadState perThread)
@@ -409,7 +455,7 @@ namespace Lucene.Net.Index
{
// LUCENENET specific - Since we need to mimic the unfair behavior of ReentrantLock, we need to ensure that all threads that enter here hold the lock.
Debugging.Assert(perThread.IsHeldByCurrentThread);
- Debugging.Assert(Monitor.IsEntered(this));
+ Debugging.Assert(UninterruptableMonitor.IsEntered(this));
Debugging.Assert(perThread.flushPending);
}
try
@@ -447,7 +493,8 @@ namespace Lucene.Net.Index
{
int numPending;
bool fullFlush;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
DocumentsWriterPerThread poll;
if (flushQueue.Count > 0 && (poll = flushQueue.Dequeue()) != null)
@@ -458,6 +505,10 @@ namespace Lucene.Net.Index
fullFlush = this.fullFlush;
numPending = this.numPending;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (numPending > 0 && !fullFlush) // don't check if we are doing a full flush
{
int limit = perThreadPool.NumThreadStatesActive;
@@ -486,7 +537,8 @@ namespace Lucene.Net.Index
internal void SetClosed()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// set by DW to signal that we should not release new DWPT after close
if (!closed)
@@ -495,6 +547,10 @@ namespace Lucene.Net.Index
perThreadPool.DeactivateUnreleasedStates();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -551,11 +607,16 @@ namespace Lucene.Net.Index
internal void DoOnDelete()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// pass null this is a global delete no update
flushPolicy.OnDelete(this, null);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -569,10 +630,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return flushingWriters.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -617,7 +683,8 @@ namespace Lucene.Net.Index
internal void MarkForFullFlush()
{
DocumentsWriterDeleteQueue flushingQueue;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled)
{
@@ -631,6 +698,10 @@ namespace Lucene.Net.Index
DocumentsWriterDeleteQueue newQueue = new DocumentsWriterDeleteQueue(flushingQueue.generation + 1);
documentsWriter.deleteQueue = newQueue;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
int limit = perThreadPool.NumThreadStatesActive;
for (int i = 0; i < limit; i++)
{
@@ -662,7 +733,8 @@ namespace Lucene.Net.Index
next.Unlock();
}
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
/* make sure we move all DWPT that are where concurrently marked as
* pending and moved to blocked are moved over to the flushQueue. There is
@@ -678,6 +750,10 @@ namespace Lucene.Net.Index
fullFlushBuffer.Clear();
UpdateStallState();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (Debugging.AssertsEnabled) Debugging.Assert(AssertActiveDeleteQueue(documentsWriter.deleteQueue));
}
@@ -718,7 +794,8 @@ namespace Lucene.Net.Index
}
if (dwpt.NumDocsInRAM > 0)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!perThread.flushPending)
{
@@ -732,6 +809,10 @@ namespace Lucene.Net.Index
}
fullFlushBuffer.Add(flushingDWPT);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
else
{
@@ -764,7 +845,8 @@ namespace Lucene.Net.Index
internal void FinishFullFlush()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled)
{
@@ -787,6 +869,10 @@ namespace Lucene.Net.Index
UpdateStallState();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal bool AssertBlockedFlushes(DocumentsWriterDeleteQueue flushingQueue)
@@ -800,7 +886,8 @@ namespace Lucene.Net.Index
internal void AbortFullFlushes(ISet<string> newFiles)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
try
{
@@ -811,11 +898,16 @@ namespace Lucene.Net.Index
fullFlush = false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void AbortPendingFlushes(ISet<string> newFiles)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
try
{
@@ -860,6 +952,10 @@ namespace Lucene.Net.Index
UpdateStallState();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -869,10 +965,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return fullFlush;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -884,10 +985,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return flushQueue.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -900,10 +1006,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return blockedFlushes.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs b/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs
index 1c5dd96..6fafb00 100644
--- a/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs
@@ -1,4 +1,4 @@
-using J2N.Threading.Atomic;
+using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support.Threading;
using System.Collections.Generic;
@@ -40,7 +40,8 @@ namespace Lucene.Net.Index
internal virtual void AddDeletes(DocumentsWriterDeleteQueue deleteQueue)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
IncTickets(); // first inc the ticket count - freeze opens
// a window for #anyChanges to fail
@@ -58,6 +59,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void IncTickets()
@@ -74,7 +79,8 @@ namespace Lucene.Net.Index
internal virtual SegmentFlushTicket AddFlushTicket(DocumentsWriterPerThread dwpt)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Each flush is assigned a ticket in the order they acquire the ticketQueue
// lock
@@ -96,25 +102,39 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void AddSegment(SegmentFlushTicket ticket, FlushedSegment segment)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// the actual flush is done asynchronously and once done the FlushedSegment
// is passed to the flush ticket
ticket.SetSegment(segment);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void MarkTicketFailed(SegmentFlushTicket ticket)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// to free the queue we mark tickets as failed just to clean up the queue.
ticket.SetFailed();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual bool HasTickets
@@ -134,11 +154,16 @@ namespace Lucene.Net.Index
{
FlushTicket head;
bool canPublish;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
head = queue.Count <= 0 ? null : queue.Peek();
canPublish = head != null && head.CanPublish; // do this synced
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (canPublish)
{
numPurged++;
@@ -154,13 +179,18 @@ namespace Lucene.Net.Index
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// finally remove the published ticket from the queue
FlushTicket poll = queue.Dequeue();
ticketCount.DecrementAndGet();
if (Debugging.AssertsEnabled) Debugging.Assert(poll == head);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
else
@@ -175,8 +205,8 @@ namespace Lucene.Net.Index
{
if (Debugging.AssertsEnabled)
{
- Debugging.Assert(!Monitor.IsEntered(this));
- Debugging.Assert(!Monitor.IsEntered(writer));
+ Debugging.Assert(!UninterruptableMonitor.IsEntered(this));
+ Debugging.Assert(!UninterruptableMonitor.IsEntered(writer));
}
purgeLock.@Lock();
try
@@ -193,8 +223,8 @@ namespace Lucene.Net.Index
{
if (Debugging.AssertsEnabled)
{
- Debugging.Assert(!Monitor.IsEntered(this));
- Debugging.Assert(!Monitor.IsEntered(writer));
+ Debugging.Assert(!UninterruptableMonitor.IsEntered(this));
+ Debugging.Assert(!UninterruptableMonitor.IsEntered(writer));
}
if (purgeLock.TryLock())
{
@@ -214,11 +244,16 @@ namespace Lucene.Net.Index
internal virtual void Clear()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
queue.Clear();
ticketCount.Value = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal abstract class FlushTicket
diff --git a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
index 349af3c..1e5af16 100644
--- a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
@@ -239,7 +239,8 @@ namespace Lucene.Net.Index
private bool AssertUnreleasedThreadStatesInactive()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
for (int i = numThreadStatesActive; i < threadStates.Length; i++)
{
@@ -255,6 +256,10 @@ namespace Lucene.Net.Index
}
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -262,7 +267,8 @@ namespace Lucene.Net.Index
/// </summary>
internal void DeactivateUnreleasedStates()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
for (int i = numThreadStatesActive; i < threadStates.Length; i++)
{
@@ -278,6 +284,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal static DocumentsWriterPerThread Reset(ThreadState threadState, bool closed) // LUCENENET: CA1822: Mark members as static
@@ -306,7 +316,8 @@ namespace Lucene.Net.Index
public ThreadState GetAndLock(/* Thread requestingThread, DocumentsWriter documentsWriter // LUCENENET: Not referenced */)
{
ThreadState threadState = null;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
for (;;)
{
@@ -352,7 +363,7 @@ namespace Lucene.Net.Index
// Wait until a thread state frees up:
try
{
- Monitor.Wait(this);
+ UninterruptableMonitor.Wait(this);
}
catch (Exception ie) when (ie.IsInterruptedException())
{
@@ -361,6 +372,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// This could take time, e.g. if the threadState is [briefly] checked for flushing:
threadState.Lock();
@@ -371,13 +386,18 @@ namespace Lucene.Net.Index
public void Release(ThreadState state)
{
state.Unlock();
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Debug.Assert(freeCount < freeList.Length);
freeList[freeCount++] = state;
// In case any thread is waiting, wake one of them up since we just released a thread state; notify() should be sufficient but we do
// notifyAll defensively:
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
diff --git a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
index fad1ab4..3f24887 100644
--- a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
@@ -1,6 +1,7 @@
using J2N.Runtime.CompilerServices;
using J2N.Threading;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -58,14 +59,19 @@ namespace Lucene.Net.Index
/// </summary>
internal void UpdateStalled(bool stalled)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
this.stalled = stalled;
if (stalled)
{
wasStalled = true;
}
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
@@ -77,7 +83,8 @@ namespace Lucene.Net.Index
{
if (stalled)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (stalled) // react on the first wakeup call!
{
@@ -88,7 +95,7 @@ namespace Lucene.Net.Index
// disabled in production
var result = IncWaiters();
if (Debugging.AssertsEnabled) Debugging.Assert(result);
- Monitor.Wait(this);
+ UninterruptableMonitor.Wait(this);
result = DecrWaiters();
if (Debugging.AssertsEnabled) Debugging.Assert(result);
}
@@ -98,6 +105,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -128,10 +139,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return numWaiting > 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -139,20 +155,30 @@ namespace Lucene.Net.Index
internal bool IsThreadQueued(ThreadJob t) // for tests
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return waiting.ContainsKey(t);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal bool WasStalled // for tests
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return wasStalled;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net/Index/FieldInfos.cs b/src/Lucene.Net/Index/FieldInfos.cs
index 9283d06..d8d05bd 100644
--- a/src/Lucene.Net/Index/FieldInfos.cs
+++ b/src/Lucene.Net/Index/FieldInfos.cs
@@ -1,5 +1,6 @@
using J2N.Collections.Generic.Extensions;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -211,7 +212,8 @@ namespace Lucene.Net.Index
/// </summary>
internal int AddOrGet(string fieldName, int preferredFieldNumber, DocValuesType dvType)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (dvType != DocValuesType.NONE)
{
@@ -249,12 +251,17 @@ namespace Lucene.Net.Index
return (int)fieldNumber;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// used by assert
internal bool ContainsConsistent(int? number, string name, DocValuesType dvType)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
numberToName.TryGetValue(number, out string numberToNameStr);
nameToNumber.TryGetValue(name, out int? nameToNumberVal);
@@ -264,6 +271,10 @@ namespace Lucene.Net.Index
&& number.Equals(nameToNumber[name]) &&
(dvType == DocValuesType.NONE || docValuesType == DocValuesType.NONE || dvType == docValuesType);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -272,7 +283,8 @@ namespace Lucene.Net.Index
/// </summary>
internal bool Contains(string fieldName, DocValuesType dvType)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// used by IndexWriter.updateNumericDocValue
if (!nameToNumber.ContainsKey(fieldName))
@@ -286,25 +298,39 @@ namespace Lucene.Net.Index
return dvType == dvCand;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void Clear()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
numberToName.Clear();
nameToNumber.Clear();
docValuesType.Clear();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void SetDocValuesType(int number, string name, DocValuesType dvType)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(ContainsConsistent(number, name, dvType));
docValuesType[name] = dvType;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Index/FlushPolicy.cs b/src/Lucene.Net/Index/FlushPolicy.cs
index b8c157a..51280b0 100644
--- a/src/Lucene.Net/Index/FlushPolicy.cs
+++ b/src/Lucene.Net/Index/FlushPolicy.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
namespace Lucene.Net.Index
@@ -95,11 +96,16 @@ namespace Lucene.Net.Index
/// </summary>
protected internal virtual void Init(LiveIndexWriterConfig indexWriterConfig)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
this.m_indexWriterConfig = indexWriterConfig;
m_infoStream = indexWriterConfig.InfoStream;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net/Index/IndexFileDeleter.cs b/src/Lucene.Net/Index/IndexFileDeleter.cs
index 107c250..fa7cd3f 100644
--- a/src/Lucene.Net/Index/IndexFileDeleter.cs
+++ b/src/Lucene.Net/Index/IndexFileDeleter.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -118,7 +119,7 @@ namespace Lucene.Net.Index
// called only from assert
private bool IsLocked =>
- writer == null || Monitor.IsEntered(writer);
+ writer == null || UninterruptableMonitor.IsEntered(writer);
/// <summary>
/// Initialize the deleter: find all previous commits in
@@ -496,7 +497,7 @@ namespace Lucene.Net.Index
{
Debugging.Assert(IsLocked);
- Debugging.Assert(Monitor.IsEntered(writer));
+ Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
}
long t0 = 0;
if (infoStream.IsEnabled("IFD"))
diff --git a/src/Lucene.Net/Index/IndexReader.cs b/src/Lucene.Net/Index/IndexReader.cs
index c75c80b..2e30b45 100644
--- a/src/Lucene.Net/Index/IndexReader.cs
+++ b/src/Lucene.Net/Index/IndexReader.cs
@@ -1,6 +1,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Documents;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections;
@@ -145,17 +146,26 @@ namespace Lucene.Net.Index
EnsureOpen();
// LUCENENET specific - since neither WeakDictionary nor ConditionalWeakTable synchronize
// on the enumerator, we need to do external synchronization to make them threadsafe.
- lock (parentReadersLock)
+ UninterruptableMonitor.Enter(parentReadersLock);
+ try
+ {
// LUCENENET: Since there is a set Add operation (unique) in Lucene, the equivalent
// operation in .NET is AddOrUpdate, which effectively does nothing if the key exists.
// Null is passed as a value, since it is not used anyway and .NET doesn't have a boolean
// reference type.
parentReaders.AddOrUpdate(key: reader, value: null);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(parentReadersLock);
+ }
}
private void NotifyReaderClosedListeners(Exception th)
{
- lock (((ICollection)readerClosedListeners).SyncRoot) // LUCENENET: Ensure we sync on the SyncRoot of ConcurrentSet<T>
+ object syncRoot = ((ICollection)readerClosedListeners).SyncRoot;
+ UninterruptableMonitor.Enter(syncRoot); // LUCENENET: Ensure we sync on the SyncRoot of ConcurrentSet<T>
+ try
{
foreach (IReaderClosedListener listener in readerClosedListeners)
{
@@ -177,13 +187,18 @@ namespace Lucene.Net.Index
}
IOUtils.ReThrowUnchecked(th);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncRoot);
+ }
}
private void ReportCloseToParentReaders()
{
// LUCENENET specific - since neither WeakDictionary nor ConditionalWeakTable synchronize
// on the enumerator, we need to do external synchronization to make them threadsafe.
- lock (parentReadersLock)
+ UninterruptableMonitor.Enter(parentReadersLock);
+ try
{
foreach (var kvp in parentReaders)
{
@@ -201,6 +216,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(parentReadersLock);
+ }
}
/// <summary>
@@ -568,7 +587,8 @@ namespace Lucene.Net.Index
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!closed)
{
@@ -576,6 +596,10 @@ namespace Lucene.Net.Index
closed = true;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index adda7ea..6e320fe 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -4,6 +4,7 @@ using J2N.Threading;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -372,7 +373,8 @@ namespace Lucene.Net.Index
bool success2 = false;
try
{
- lock (fullFlushLock)
+ UninterruptableMonitor.Enter(fullFlushLock);
+ try
{
bool success = false;
try
@@ -388,7 +390,8 @@ namespace Lucene.Net.Index
// Prevent segmentInfos from changing while opening the
// reader; in theory we could instead do similar retry logic,
// just like we do when loading segments_N
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeApplyDeletes(applyAllDeletes);
r = StandardDirectoryReader.Open(this, segmentInfos, applyAllDeletes);
@@ -397,6 +400,10 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "return reader version=" + r.Version + " reader=" + r);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
{
@@ -419,6 +426,10 @@ namespace Lucene.Net.Index
DoAfterFlush();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(fullFlushLock);
+ }
if (anySegmentFlushed)
{
MaybeMerge(MergeTrigger.FULL_FLUSH, UNBOUNDED_MAX_MERGE_SEGMENTS);
@@ -467,18 +478,24 @@ namespace Lucene.Net.Index
// used only by asserts
public virtual bool InfoIsLive(SegmentCommitInfo info)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int idx = outerInstance.segmentInfos.IndexOf(info);
Debugging.Assert(idx != -1, "info={0} isn't live", info);
Debugging.Assert(outerInstance.segmentInfos.Info(idx) == info, "info={0} doesn't match live info in segmentInfos", info);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void Drop(SegmentCommitInfo info)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (readerMap.TryGetValue(info, out ReadersAndUpdates rld) && rld != null)
{
@@ -488,11 +505,16 @@ namespace Lucene.Net.Index
rld.DropReaders();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual bool AnyPendingDeletes()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (ReadersAndUpdates rld in readerMap.Values)
{
@@ -504,19 +526,29 @@ namespace Lucene.Net.Index
return false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void Release(ReadersAndUpdates rld)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Release(rld, true);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void Release(ReadersAndUpdates rld, bool assertInfoLive)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Matches incRef in get:
rld.DecRef();
@@ -549,6 +581,10 @@ namespace Lucene.Net.Index
readerMap.Remove(rld.Info);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public void Dispose()
@@ -562,7 +598,8 @@ namespace Lucene.Net.Index
/// </summary>
internal virtual void DropAll(bool doSave)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Exception priorE = null;
foreach (var pair in readerMap)
@@ -628,6 +665,10 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(readerMap.Count == 0);
IOUtils.ReThrow(priorE);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -637,7 +678,8 @@ namespace Lucene.Net.Index
/// <exception cref="IOException"> If there is a low-level I/O error </exception>
public virtual void Commit(SegmentInfos infos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (SegmentCommitInfo info in infos.Segments)
{
@@ -660,6 +702,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -669,7 +715,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual ReadersAndUpdates Get(SegmentCommitInfo info, bool create)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(info.Info.Dir == outerInstance.directory, "info.dir={0} vs {1}", info.Info.Dir, outerInstance.directory);
@@ -699,6 +746,10 @@ namespace Lucene.Net.Index
return rld;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -896,10 +947,15 @@ namespace Lucene.Net.Index
// Default deleter (for backwards compatibility) is
// KeepOnlyLastCommitDeleter:
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter = new IndexFileDeleter(directory, config.IndexDeletionPolicy, segmentInfos, infoStream, this, initialIndexExists);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (deleter.startingCommitDeleted)
{
@@ -1060,7 +1116,8 @@ namespace Lucene.Net.Index
{
// Ensure that only one thread actually gets to do the
// closing, and make sure no commit is also in progress:
- lock (commitLock)
+ UninterruptableMonitor.Enter(commitLock);
+ try
{
if (ShouldClose())
{
@@ -1078,6 +1135,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(commitLock);
+ }
}
private bool AssertEventQueueAfterClose()
@@ -1100,7 +1161,8 @@ namespace Lucene.Net.Index
/// </summary>
private bool ShouldClose()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (true)
{
@@ -1125,6 +1187,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void CloseInternal(bool waitForMerges, bool doFlush)
@@ -1189,7 +1255,8 @@ namespace Lucene.Net.Index
}
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
for (; ; )
{
@@ -1212,6 +1279,10 @@ namespace Lucene.Net.Index
}
stopMerges = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
finally
{
@@ -1230,7 +1301,8 @@ namespace Lucene.Net.Index
CommitInternal();
}
ProcessEvents(false, true);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// commitInternal calls ReaderPool.commit, which
// writes any pending liveDocs from ReaderPool, so
@@ -1238,6 +1310,10 @@ namespace Lucene.Net.Index
readerPool.DropAll(true);
deleter.Dispose();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (infoStream.IsEnabled("IW"))
{
@@ -1249,10 +1325,15 @@ namespace Lucene.Net.Index
writeLock.Dispose(); // release write lock
writeLock = null;
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
closed = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (Debugging.AssertsEnabled)
{
// LUCENENET specific - store the number of states so we don't have to call this method twice
@@ -1266,10 +1347,11 @@ namespace Lucene.Net.Index
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
closing = false;
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
if (!closed)
{
if (infoStream.IsEnabled("IW"))
@@ -1278,6 +1360,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// finally, restore interrupt status:
if (interrupted)
{
@@ -1311,11 +1397,16 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
return docWriter.NumDocs + segmentInfos.TotalDocCount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -1331,7 +1422,8 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
int count = docWriter.NumDocs;
@@ -1341,6 +1433,10 @@ namespace Lucene.Net.Index
}
return count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -1353,7 +1449,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual bool HasDeletions()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
if (bufferedUpdatesStream.Any())
@@ -1377,6 +1474,10 @@ namespace Lucene.Net.Index
}
return false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -1607,7 +1708,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual bool TryDeleteDocument(IndexReader readerIn, int docID)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!(readerIn is AtomicReader reader))
{
@@ -1641,7 +1743,8 @@ namespace Lucene.Net.Index
ReadersAndUpdates rld = readerPool.Get(info, false);
if (rld != null)
{
- lock (bufferedUpdatesStream)
+ UninterruptableMonitor.Enter(bufferedUpdatesStream);
+ try
{
rld.InitWritableLiveDocs();
if (rld.Delete(docID))
@@ -1668,6 +1771,10 @@ namespace Lucene.Net.Index
//System.out.println(" yes " + info.info.name + " " + docID);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(bufferedUpdatesStream);
+ }
}
else
{
@@ -1680,6 +1787,10 @@ namespace Lucene.Net.Index
}
return false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -1928,10 +2039,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return segmentInfos.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -1940,10 +2056,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return docWriter.NumDocs;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -1952,17 +2073,23 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return segmentInfos.GetFiles(directory, true);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
// for test purpose
internal int GetDocCount(int i)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (i >= 0 && i < segmentInfos.Count)
{
@@ -1973,6 +2100,10 @@ namespace Lucene.Net.Index
return -1;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// for test purpose
@@ -1985,7 +2116,8 @@ namespace Lucene.Net.Index
{
// Cannot synchronize on IndexWriter because that causes
// deadlock
- lock (segmentInfos)
+ UninterruptableMonitor.Enter(segmentInfos);
+ try
{
// Important to increment changeCount so that the
// segmentInfos is written on close. Otherwise we
@@ -1996,6 +2128,10 @@ namespace Lucene.Net.Index
segmentInfos.Changed();
return "_" + (segmentInfos.Counter++).ToString(J2N.Character.MaxRadix);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(segmentInfos);
+ }
}
/// <summary>
@@ -2099,7 +2235,8 @@ namespace Lucene.Net.Index
Flush(true, true);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
ResetMergeExceptions();
segmentsToMerge.Clear();
@@ -2123,12 +2260,17 @@ namespace Lucene.Net.Index
if (merge.Info != null) segmentsToMerge[merge.Info] = true;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
MaybeMerge(MergeTrigger.EXPLICIT, maxNumSegments);
if (doWait)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (true)
{
@@ -2170,6 +2312,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// If close is called while we are still
// running, throw an exception so the calling
@@ -2177,6 +2323,7 @@ namespace Lucene.Net.Index
// complete
EnsureOpen();
}
+
// NOTE: in the ConcurrentMergeScheduler case, when
// doWait is false, we can return immediately while
// background threads accomplish the merging
@@ -2188,7 +2335,8 @@ namespace Lucene.Net.Index
/// </summary>
private bool MaxNumSegmentsMergesPending()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (MergePolicy.OneMerge merge in pendingMerges)
{
@@ -2208,6 +2356,10 @@ namespace Lucene.Net.Index
return false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2239,7 +2391,9 @@ namespace Lucene.Net.Index
MergePolicy.MergeSpecification spec;
bool newMergesFound = false;
- lock (this)
+
+ UninterruptableMonitor.Enter(this);
+ try
{
spec = mergePolicy.FindForcedDeletesMerges(segmentInfos);
newMergesFound = spec != null;
@@ -2252,13 +2406,18 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
mergeScheduler.Merge(this, MergeTrigger.EXPLICIT, newMergesFound);
if (spec != null && doWait)
{
int numMerges = spec.Merges.Count;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
bool running = true;
while (running)
@@ -2293,6 +2452,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// NOTE: in the ConcurrentMergeScheduler case, when
@@ -2359,7 +2522,8 @@ namespace Lucene.Net.Index
private bool UpdatePendingMerges(MergeTrigger trigger, int maxNumSegments)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(maxNumSegments == -1 || maxNumSegments > 0);
//if (Debugging.AssertsEnabled) Debugging.Assert(trigger != null); // LUCENENET NOTE: Enum cannot be null in .NET
@@ -2377,7 +2541,7 @@ namespace Lucene.Net.Index
MergePolicy.MergeSpecification spec;
if (maxNumSegments != UNBOUNDED_MAX_MERGE_SEGMENTS)
{
- if (Debugging.AssertsEnabled) Debugging.Assert(trigger == MergeTrigger.EXPLICIT || trigger == MergeTrigger.MERGE_FINISHED,"Expected EXPLICT or MERGE_FINISHED as trigger even with maxNumSegments set but was: {0}", trigger);
+ if (Debugging.AssertsEnabled) Debugging.Assert(trigger == MergeTrigger.EXPLICIT || trigger == MergeTrigger.MERGE_FINISHED, "Expected EXPLICT or MERGE_FINISHED as trigger even with maxNumSegments set but was: {0}", trigger);
spec = mergePolicy.FindForcedMerges(segmentInfos, maxNumSegments, segmentsToMerge);
newMergesFound = spec != null;
if (newMergesFound)
@@ -2405,6 +2569,10 @@ namespace Lucene.Net.Index
}
return newMergesFound;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2421,10 +2589,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return mergingSegments;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -2436,7 +2609,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual MergePolicy.OneMerge NextMerge()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (pendingMerges.Count == 0)
{
@@ -2450,6 +2624,10 @@ namespace Lucene.Net.Index
return merge;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2459,10 +2637,15 @@ namespace Lucene.Net.Index
/// </summary>
public virtual bool HasPendingMerges()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return pendingMerges.Count != 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2482,13 +2665,18 @@ namespace Lucene.Net.Index
// Ensure that only one thread actually gets to do the
// closing, and make sure no commit is also in progress:
- lock (commitLock)
+ UninterruptableMonitor.Enter(commitLock);
+ try
{
if (ShouldClose())
{
RollbackInternal();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(commitLock);
+ }
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -2503,11 +2691,16 @@ namespace Lucene.Net.Index
try
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
FinishMerges(false);
stopMerges = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (infoStream.IsEnabled("IW"))
{
@@ -2523,14 +2716,15 @@ namespace Lucene.Net.Index
bufferedUpdatesStream.Clear();
docWriter.Dispose(); // mark it as closed first to prevent subsequent indexing actions/flushes
docWriter.Abort(this); // don't sync on IW here
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (pendingCommit != null)
{
pendingCommit.RollbackCommit(directory);
deleter.DecRef(pendingCommit);
pendingCommit = null;
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
}
// Don't bother saving any changes in our segmentInfos
@@ -2569,6 +2763,10 @@ namespace Lucene.Net.Index
Debugging.Assert(numDeactivatedThreadStates == docWriter.perThreadPool.MaxThreadStates, "{0} {1}", numDeactivatedThreadStates, docWriter.perThreadPool.MaxThreadStates);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
success = true;
}
@@ -2585,7 +2783,8 @@ namespace Lucene.Net.Index
// e.g. TestIW.testThreadInterruptDeadlock
IOUtils.DisposeWhileHandlingException(mergePolicy, mergeScheduler);
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!success)
{
@@ -2611,6 +2810,10 @@ namespace Lucene.Net.Index
closed = true;
closing = false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -2644,7 +2847,8 @@ namespace Lucene.Net.Index
/* hold the full flush lock to prevent concurrency commits / NRT reopens to
* get in our way and do unnecessary work. -- if we don't lock this here we might
* get in trouble if */
- lock (fullFlushLock)
+ UninterruptableMonitor.Enter(fullFlushLock);
+ try
{
/*
* We first abort and trash everything we have in-memory
@@ -2659,7 +2863,8 @@ namespace Lucene.Net.Index
{
docWriter.LockAndAbortAll(this);
ProcessEvents(false, true);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
try
{
@@ -2698,17 +2903,26 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
finally
{
docWriter.UnlockAllAfterAbortAll(this);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(fullFlushLock);
+ }
}
private void FinishMerges(bool waitForMerges)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!waitForMerges)
{
@@ -2750,7 +2964,7 @@ namespace Lucene.Net.Index
}
stopMerges = false;
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
if (Debugging.AssertsEnabled) Debugging.Assert(0 == mergingSegments.Count);
@@ -2769,6 +2983,10 @@ namespace Lucene.Net.Index
WaitForMerges();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2779,7 +2997,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void WaitForMerges()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen(false);
if (infoStream.IsEnabled("IW"))
@@ -2799,6 +3018,10 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "waitForMerges done");
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2808,11 +3031,16 @@ namespace Lucene.Net.Index
/// </summary>
internal virtual void Checkpoint()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Changed();
deleter.Checkpoint(segmentInfos, false);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -2823,33 +3051,53 @@ namespace Lucene.Net.Index
/// </summary>
internal virtual void CheckpointNoSIS()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
changeCount++;
deleter.Checkpoint(segmentInfos, false);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
/// Called internally if any index state has changed. </summary>
internal void Changed()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
changeCount++;
segmentInfos.Changed();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void PublishFrozenUpdates(FrozenBufferedUpdates packet)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(packet != null && packet.Any());
- lock (bufferedUpdatesStream)
+ UninterruptableMonitor.Enter(bufferedUpdatesStream);
+ try
{
bufferedUpdatesStream.Push(packet);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(bufferedUpdatesStream);
+ }
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
@@ -2861,10 +3109,12 @@ namespace Lucene.Net.Index
{
try
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Lock order IW -> BDS
- lock (bufferedUpdatesStream)
+ UninterruptableMonitor.Enter(bufferedUpdatesStream);
+ try
{
if (infoStream.IsEnabled("IW"))
{
@@ -2896,6 +3146,14 @@ namespace Lucene.Net.Index
segmentInfos.Add(newSegment);
Checkpoint();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(bufferedUpdatesStream);
+ }
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
finally
@@ -2907,11 +3165,16 @@ namespace Lucene.Net.Index
private void ResetMergeExceptions()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
mergeExceptions = new List<MergePolicy.OneMerge>();
mergeGen++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void NoDupDirs(params Directory[] dirs)
@@ -3081,7 +3344,8 @@ namespace Lucene.Net.Index
}
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
success = false;
try
@@ -3111,6 +3375,10 @@ namespace Lucene.Net.Index
segmentInfos.AddAll(infos);
Checkpoint();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
successTop = true;
}
@@ -3219,10 +3487,15 @@ namespace Lucene.Net.Index
{
if (!success)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.Refresh(info.Name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -3234,7 +3507,8 @@ namespace Lucene.Net.Index
SetDiagnostics(info, SOURCE_ADDINDEXES_READERS);
bool useCompoundFile;
- lock (this) // Guard segmentInfos
+ UninterruptableMonitor.Enter(this); // Guard segmentInfos
+ try
{
if (stopMerges)
{
@@ -3244,6 +3518,10 @@ namespace Lucene.Net.Index
EnsureOpen();
useCompoundFile = mergePolicy.UseCompoundFile(segmentInfos, infoPerCommit);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// Now create the compound file if needed
if (useCompoundFile)
@@ -3257,10 +3535,15 @@ namespace Lucene.Net.Index
{
// delete new non cfs files directly: they were never
// registered with IFD
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.DeleteNewFiles(filesToDelete);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
info.UseCompoundFile = true;
}
@@ -3279,17 +3562,23 @@ namespace Lucene.Net.Index
{
if (!success)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.Refresh(info.Name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
info.AddFiles(trackingDir.CreatedFiles);
// Register the new segment
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (stopMerges)
{
@@ -3300,6 +3589,10 @@ namespace Lucene.Net.Index
segmentInfos.Add(infoPerCommit);
Checkpoint();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
{
@@ -3502,7 +3795,8 @@ namespace Lucene.Net.Index
private void PrepareCommitInternal()
{
- lock (commitLock)
+ UninterruptableMonitor.Enter(commitLock);
+ try
{
EnsureOpen(false);
if (infoStream.IsEnabled("IW"))
@@ -3533,7 +3827,8 @@ namespace Lucene.Net.Index
try
{
- lock (fullFlushLock)
+ UninterruptableMonitor.Enter(fullFlushLock);
+ try
{
bool flushSuccess = false;
bool success = false;
@@ -3549,7 +3844,8 @@ namespace Lucene.Net.Index
ProcessEvents(false, true);
flushSuccess = true;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeApplyDeletes(true);
@@ -3572,6 +3868,10 @@ namespace Lucene.Net.Index
filesToCommit = toCommit.GetFiles(directory, false);
deleter.IncRef(filesToCommit);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
success = true;
}
finally
@@ -3588,6 +3888,10 @@ namespace Lucene.Net.Index
DoAfterFlush();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(fullFlushLock);
+ }
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
{
@@ -3608,7 +3912,8 @@ namespace Lucene.Net.Index
{
if (!success_)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (filesToCommit != null)
{
@@ -3616,9 +3921,17 @@ namespace Lucene.Net.Index
filesToCommit = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(commitLock);
+ }
}
/// <summary>
@@ -3633,11 +3946,16 @@ namespace Lucene.Net.Index
/// </summary>
public void SetCommitData(IDictionary<string, string> commitUserData)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
segmentInfos.UserData = new Dictionary<string, string>(commitUserData);
++changeCount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -3648,10 +3966,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return segmentInfos.UserData;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -3717,7 +4040,8 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "commit: start");
}
- lock (commitLock)
+ UninterruptableMonitor.Enter(commitLock);
+ try
{
EnsureOpen(false);
@@ -3744,11 +4068,16 @@ namespace Lucene.Net.Index
FinishCommit();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(commitLock);
+ }
}
private void FinishCommit()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (pendingCommit != null)
{
@@ -3776,7 +4105,7 @@ namespace Lucene.Net.Index
deleter.DecRef(filesToCommit);
filesToCommit = null;
pendingCommit = null;
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
}
}
else
@@ -3792,6 +4121,10 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "commit: done");
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -3801,7 +4134,7 @@ namespace Lucene.Net.Index
private readonly object fullFlushLock = new object();
// for assert
- internal virtual bool HoldsFullFlushLock => Monitor.IsEntered(fullFlushLock);
+ internal virtual bool HoldsFullFlushLock => UninterruptableMonitor.IsEntered(fullFlushLock);
/// <summary>
/// Flush all in-memory buffered updates (adds and deletes)
@@ -3847,7 +4180,8 @@ namespace Lucene.Net.Index
}
bool anySegmentFlushed;
- lock (fullFlushLock)
+ UninterruptableMonitor.Enter(fullFlushLock);
+ try
{
bool flushSuccess = false;
try
@@ -3861,7 +4195,12 @@ namespace Lucene.Net.Index
ProcessEvents(false, true);
}
}
- lock (this)
+ finally
+ {
+ UninterruptableMonitor.Exit(fullFlushLock);
+ }
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeApplyDeletes(applyAllDeletes);
DoAfterFlush();
@@ -3873,6 +4212,10 @@ namespace Lucene.Net.Index
success = true;
return anySegmentFlushed;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
{
@@ -3894,7 +4237,8 @@ namespace Lucene.Net.Index
internal void MaybeApplyDeletes(bool applyAllDeletes)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (applyAllDeletes)
{
@@ -3909,11 +4253,16 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "don't apply deletes now delTermCount=" + bufferedUpdatesStream.NumTerms + " bytesUsed=" + bufferedUpdatesStream.BytesUsed);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal void ApplyAllDeletesAndUpdates()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
flushDeletesCount.IncrementAndGet();
BufferedUpdatesStream.ApplyDeletesResult result;
@@ -3944,6 +4293,10 @@ namespace Lucene.Net.Index
}
bufferedUpdatesStream.Prune(segmentInfos);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -3966,16 +4319,22 @@ namespace Lucene.Net.Index
/// </summary>
public int NumRamDocs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
return docWriter.NumDocs;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void EnsureValidMerge(MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (SegmentCommitInfo info in merge.Segments)
{
@@ -3985,6 +4344,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private static void SkipDeletedDoc(DocValuesFieldUpdates.Iterator[] updatesIters, int deletedDoc) // LUCENENET: CA1822: Mark members as static
@@ -4067,7 +4430,8 @@ namespace Lucene.Net.Index
/// </summary>
private ReadersAndUpdates CommitMergedDeletesAndUpdates(MergePolicy.OneMerge merge, MergeState mergeState)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(TestPoint("startCommitMergeDeletes"));
@@ -4095,7 +4459,7 @@ namespace Lucene.Net.Index
IBits prevLiveDocs = merge.readers[i].LiveDocs;
ReadersAndUpdates rld = readerPool.Get(info, false);
// We hold a ref so it should still be in the pool:
- if (Debugging.AssertsEnabled) Debugging.Assert(rld != null,"seg={0}", info.Info.Name);
+ if (Debugging.AssertsEnabled) Debugging.Assert(rld != null, "seg={0}", info.Info.Name);
IBits currentLiveDocs = rld.LiveDocs;
IDictionary<string, DocValuesFieldUpdates> mergingFieldUpdates = rld.MergingFieldUpdates;
string[] mergingFields;
@@ -4302,11 +4666,16 @@ namespace Lucene.Net.Index
return holder.mergedDeletesAndUpdates;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool CommitMerge(MergePolicy.OneMerge merge, MergeState mergeState)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(TestPoint("startCommitMerge"));
@@ -4463,6 +4832,10 @@ namespace Lucene.Net.Index
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void HandleMergeException(Exception t, MergePolicy.OneMerge merge)
@@ -4537,7 +4910,8 @@ namespace Lucene.Net.Index
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MergeFinish(merge);
@@ -4561,6 +4935,10 @@ namespace Lucene.Net.Index
UpdatePendingMerges(MergeTrigger.MERGE_FINISHED, merge.MaxNumSegments);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
@@ -4592,7 +4970,8 @@ namespace Lucene.Net.Index
/// </summary>
internal bool RegisterMerge(MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (merge.registerDone)
{
@@ -4697,6 +5076,10 @@ namespace Lucene.Net.Index
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -4705,7 +5088,8 @@ namespace Lucene.Net.Index
/// </summary>
internal void MergeInit(MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
bool success = false;
try
@@ -4725,11 +5109,16 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void MergeInitImpl(MergePolicy.OneMerge merge) // LUCENENET specific: renamed from _mergeInit
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled)
{
@@ -4810,6 +5199,10 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "merge seg=" + merge.info.Info.Name + " " + SegString(merge.Segments));
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal static void SetDiagnostics(SegmentInfo info, string source)
@@ -4843,11 +5236,12 @@ namespace Lucene.Net.Index
/// </summary>
public void MergeFinish(MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// forceMerge, addIndexes or finishMerges may be waiting
// on merges to finish.
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
// It's possible we are called twice, eg if there was an
// exception inside mergeInit
@@ -4863,11 +5257,16 @@ namespace Lucene.Net.Index
runningMerges.Remove(merge);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void CloseMergeReaders(MergePolicy.OneMerge merge, bool suppressExceptions)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int numSegments = merge.readers.Count;
Exception th = null;
@@ -4916,6 +5315,10 @@ namespace Lucene.Net.Index
IOUtils.ReThrow(th);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -4962,7 +5365,8 @@ namespace Lucene.Net.Index
IBits liveDocs;
int delCount;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Must sync to ensure BufferedDeletesStream cannot change liveDocs,
// pendingDeleteCount and field updates while we pull a copy:
@@ -4992,6 +5396,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// Deletes might have happened after we pulled the merge reader and
// before we got a read-only copy of the segment's actual live docs
@@ -5053,10 +5461,15 @@ namespace Lucene.Net.Index
{
if (!success3)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.Refresh(merge.info.Info.Name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
if (Debugging.AssertsEnabled) Debugging.Assert(mergeState.SegmentInfo == merge.info.Info);
@@ -5081,10 +5494,15 @@ namespace Lucene.Net.Index
// this segment:
//System.out.println("merger set hasProx=" + merger.hasProx() + " seg=" + merge.info.name);
bool useCompoundFile;
- lock (this) // Guard segmentInfos
+ UninterruptableMonitor.Enter(this); // Guard segmentInfos
+ try
{
useCompoundFile = mergePolicy.UseCompoundFile(segmentInfos, merge.info);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (useCompoundFile)
{
@@ -5099,7 +5517,8 @@ namespace Lucene.Net.Index
}
catch (Exception ioe) when (ioe.IsIOException())
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (merge.IsAborted)
{
@@ -5112,6 +5531,10 @@ namespace Lucene.Net.Index
HandleMergeException(ioe, merge);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
catch (Exception t) when (t.IsThrowable())
{
@@ -5126,12 +5549,17 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "hit exception creating compound file during merge");
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.DeleteFile(Lucene.Net.Index.IndexFileNames.SegmentFileName(mergedName, "", Lucene.Net.Index.IndexFileNames.COMPOUND_FILE_EXTENSION));
deleter.DeleteFile(Lucene.Net.Index.IndexFileNames.SegmentFileName(mergedName, "", Lucene.Net.Index.IndexFileNames.COMPOUND_FILE_ENTRIES_EXTENSION));
deleter.DeleteNewFiles(merge.info.GetFiles());
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -5140,7 +5568,8 @@ namespace Lucene.Net.Index
// per-segment readers in the finally clause below:
success = false;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// delete new non cfs files directly: they were never
// registered with IFD
@@ -5157,6 +5586,10 @@ namespace Lucene.Net.Index
return 0;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
merge.info.Info.UseCompoundFile = true;
}
@@ -5182,10 +5615,15 @@ namespace Lucene.Net.Index
{
if (!success2)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.DeleteNewFiles(merge.info.GetFiles());
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -5209,11 +5647,16 @@ namespace Lucene.Net.Index
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
rld.Release(sr);
readerPool.Release(rld);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -5243,7 +5686,8 @@ namespace Lucene.Net.Index
internal virtual void AddMergeException(MergePolicy.OneMerge merge)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(merge.Exception != null);
if (!mergeExceptions.Contains(merge) && mergeGen == merge.mergeGen)
@@ -5251,6 +5695,10 @@ namespace Lucene.Net.Index
mergeExceptions.Add(merge);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// For test purposes.
@@ -5262,10 +5710,15 @@ namespace Lucene.Net.Index
// utility routines for tests
internal virtual SegmentCommitInfo NewestSegment()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return segmentInfos.Count > 0 ? segmentInfos.Info(segmentInfos.Count - 1) : null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -5276,10 +5729,15 @@ namespace Lucene.Net.Index
/// </summary>
public virtual string SegString()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return SegString(segmentInfos.Segments);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -5290,7 +5748,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual string SegString(IEnumerable<SegmentCommitInfo> infos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
StringBuilder buffer = new StringBuilder();
foreach (SegmentCommitInfo info in infos)
@@ -5303,6 +5762,10 @@ namespace Lucene.Net.Index
}
return buffer.ToString();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -5313,15 +5776,21 @@ namespace Lucene.Net.Index
/// </summary>
public virtual string SegString(SegmentCommitInfo info)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return info.ToString(info.Info.Dir, NumDeletedDocs(info) - info.DelCount);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void DoWait()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// NOTE: the callers of this method should in theory
// be able to do simply wait(), but, as a defense
@@ -5331,13 +5800,17 @@ namespace Lucene.Net.Index
// conditions are satisfied:
try
{
- Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
+ UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(1000));
}
catch (Exception ie) when (ie.IsInterruptedException())
{
throw new Util.ThreadInterruptedException(ie);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool keepFullyDeletedSegments;
@@ -5377,7 +5850,8 @@ namespace Lucene.Net.Index
// For infoStream output
internal virtual SegmentInfos ToLiveInfos(SegmentInfos sis)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
SegmentInfos newSIS = new SegmentInfos();
IDictionary<SegmentCommitInfo, SegmentCommitInfo> liveSIS = new Dictionary<SegmentCommitInfo, SegmentCommitInfo>();
@@ -5397,6 +5871,10 @@ namespace Lucene.Net.Index
return newSIS;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -5426,7 +5904,8 @@ namespace Lucene.Net.Index
infoStream.Message("IW", "StartCommit(): start");
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(lastCommitChangeCount <= changeCount,"lastCommitChangeCount={0} changeCount={1}", lastCommitChangeCount, changeCount);
@@ -5448,6 +5927,10 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(FilesExist(toSync));
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (Debugging.AssertsEnabled) Debugging.Assert(TestPoint("midStartCommit"));
@@ -5457,7 +5940,8 @@ namespace Lucene.Net.Index
{
if (Debugging.AssertsEnabled) Debugging.Assert(TestPoint("midStartCommit2"));
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(pendingCommit == null);
@@ -5472,6 +5956,10 @@ namespace Lucene.Net.Index
pendingCommitSet = true;
pendingCommit = toSync;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// this call can take a long time -- 10s of seconds
// or more. We do it without syncing on this:
@@ -5502,7 +5990,8 @@ namespace Lucene.Net.Index
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Have our master segmentInfos record the
// generations we just prepared. We do this
@@ -5522,6 +6011,10 @@ namespace Lucene.Net.Index
filesToCommit = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
catch (Exception oom) when (oom.IsOutOfMemoryError())
@@ -5618,7 +6111,8 @@ namespace Lucene.Net.Index
internal virtual bool NrtIsCurrent(SegmentInfos infos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
//System.out.println("IW.nrtIsCurrent " + (infos.version == segmentInfos.version && !docWriter.anyChanges() && !bufferedDeletesStream.any()));
EnsureOpen();
@@ -5628,16 +6122,25 @@ namespace Lucene.Net.Index
}
return infos.Version == segmentInfos.Version && !docWriter.AnyChanges() && !bufferedUpdatesStream.Any();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual bool IsClosed
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return closed;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -5669,12 +6172,17 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void DeleteUnusedFiles()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen(false);
deleter.DeletePendingFiles();
deleter.RevisitPolicy();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// LUCENENET specific - DeletePendingFiles() excluded because it is not referenced - IDE0051
@@ -5752,10 +6260,15 @@ namespace Lucene.Net.Index
/// <seealso cref="IndexFileDeleter.DeleteNewFiles(ICollection{string})"/>
internal void DeleteNewFiles(ICollection<string> files)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.DeleteNewFiles(files);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -5763,10 +6276,15 @@ namespace Lucene.Net.Index
/// <seealso cref="IndexFileDeleter.Refresh(string)"/>
internal void FlushFailed(SegmentInfo info)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
deleter.Refresh(info.Name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal int Purge(bool forced)
@@ -5804,20 +6322,30 @@ namespace Lucene.Net.Index
internal virtual void IncRefDeleter(SegmentInfos segmentInfos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
deleter.IncRef(segmentInfos, false);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void DecRefDeleter(SegmentInfos segmentInfos)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
deleter.DecRef(segmentInfos);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool ProcessEvents(bool triggerMerge, bool forcePurge)
diff --git a/src/Lucene.Net/Index/MergePolicy.cs b/src/Lucene.Net/Index/MergePolicy.cs
index cf6f5ac..606e36c 100644
--- a/src/Lucene.Net/Index/MergePolicy.cs
+++ b/src/Lucene.Net/Index/MergePolicy.cs
@@ -1,5 +1,6 @@
using J2N.Collections.Generic.Extensions;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -229,17 +230,27 @@ namespace Lucene.Net.Index
{
set
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
this.error = value;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return error;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -251,10 +262,15 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
internal virtual void Abort()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
aborted = true;
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
@@ -264,10 +280,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return aborted;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -277,7 +298,8 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void CheckAborted(Directory dir)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (aborted)
{
@@ -290,7 +312,7 @@ namespace Lucene.Net.Index
{
//In theory we could wait() indefinitely, but we
// do 1000 msec, defensively
- Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
+ UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(1000));
}
catch (Exception ie) when (ie.IsInterruptedException())
{
@@ -303,6 +325,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -312,15 +338,20 @@ namespace Lucene.Net.Index
/// </summary>
internal virtual void SetPause(bool paused)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
this.paused = paused;
if (!paused)
{
// Wakeup merge thread, if it's waiting
- Monitor.PulseAll(this);
+ UninterruptableMonitor.PulseAll(this);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -331,10 +362,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return paused;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Index/MultiReader.cs b/src/Lucene.Net/Index/MultiReader.cs
index acbdd14..dd4d090 100644
--- a/src/Lucene.Net/Index/MultiReader.cs
+++ b/src/Lucene.Net/Index/MultiReader.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support.Threading;
+using System;
using System.IO;
using System.Runtime.ExceptionServices;
@@ -73,7 +74,8 @@ namespace Lucene.Net.Index
protected internal override void DoClose()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Exception ioe = null; // LUCENENET: No need to cast to IOExcpetion
foreach (IndexReader r in GetSequentialSubReaders())
@@ -103,6 +105,10 @@ namespace Lucene.Net.Index
ExceptionDispatchInfo.Capture(ioe).Throw(); // LUCENENET: Rethrow to preserve stack details from the original throw
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/ParallelAtomicReader.cs b/src/Lucene.Net/Index/ParallelAtomicReader.cs
index d9db780..8199766 100644
--- a/src/Lucene.Net/Index/ParallelAtomicReader.cs
+++ b/src/Lucene.Net/Index/ParallelAtomicReader.cs
@@ -1,5 +1,6 @@
using J2N.Runtime.CompilerServices;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -284,7 +285,8 @@ namespace Lucene.Net.Index
protected internal override void DoClose()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Exception ioe = null; // LUCENENET: No need to cast to IOExcpetion
foreach (AtomicReader reader in completeReaderSet)
@@ -314,6 +316,10 @@ namespace Lucene.Net.Index
ExceptionDispatchInfo.Capture(ioe).Throw(); // LUCENENET: Rethrow to preserve stack details from the original throw
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override NumericDocValues GetNumericDocValues(string field)
diff --git a/src/Lucene.Net/Index/ParallelCompositeReader.cs b/src/Lucene.Net/Index/ParallelCompositeReader.cs
index 9ada68a..437c0a8 100644
--- a/src/Lucene.Net/Index/ParallelCompositeReader.cs
+++ b/src/Lucene.Net/Index/ParallelCompositeReader.cs
@@ -1,6 +1,7 @@
using J2N.Runtime.CompilerServices;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -222,7 +223,8 @@ namespace Lucene.Net.Index
protected internal override void DoClose()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Exception ioe = null; // LUCENENET: No need to cast to IOExcpetion
foreach (IndexReader reader in completeReaderSet)
@@ -252,6 +254,10 @@ namespace Lucene.Net.Index
ExceptionDispatchInfo.Capture(ioe).Throw(); // LUCENENET: Rethrow to preserve stack details from the original throw
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs b/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
index f9bcdb9..1688718 100644
--- a/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -124,7 +125,8 @@ namespace Lucene.Net.Index
/// <seealso cref="SnapshotDeletionPolicy.Snapshot()"/>
public override IndexCommit Snapshot()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
IndexCommit ic = base.Snapshot();
bool success = false;
@@ -149,6 +151,10 @@ namespace Lucene.Net.Index
}
return ic;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -158,7 +164,8 @@ namespace Lucene.Net.Index
/// <seealso cref="SnapshotDeletionPolicy.Release(IndexCommit)"/>
public override void Release(IndexCommit commit)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
base.Release(commit);
bool success = false;
@@ -182,6 +189,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -192,17 +203,23 @@ namespace Lucene.Net.Index
/// <seealso cref="SnapshotDeletionPolicy.Release(IndexCommit)"/>
public virtual void Release(long gen)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
base.ReleaseGen(gen);
Persist();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal void Persist()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
string fileName = SNAPSHOTS_PREFIX + nextWriteGen;
IndexOutput @out = dir.CreateOutput(fileName, IOContext.DEFAULT);
@@ -255,11 +272,16 @@ namespace Lucene.Net.Index
nextWriteGen++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private void ClearPriorSnapshots()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (string file in dir.ListAll())
{
@@ -269,6 +291,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -298,7 +324,8 @@ namespace Lucene.Net.Index
/// </summary>
private void LoadPriorSnapshots()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
long genLoaded = -1;
Exception ioe = null; // LUCENENET: No need to cast to IOExcpetion
@@ -371,6 +398,10 @@ namespace Lucene.Net.Index
nextWriteGen = 1 + genLoaded;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/ReadersAndUpdates.cs b/src/Lucene.Net/Index/ReadersAndUpdates.cs
index 6cd440a..8dcfde1 100644
--- a/src/Lucene.Net/Index/ReadersAndUpdates.cs
+++ b/src/Lucene.Net/Index/ReadersAndUpdates.cs
@@ -1,6 +1,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -125,17 +126,23 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return pendingDeleteCount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
// Call only from assert!
public virtual bool VerifyDocCounts()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int count;
if (liveDocs != null)
@@ -157,6 +164,10 @@ namespace Lucene.Net.Index
if (Debugging.AssertsEnabled) Debugging.Assert(Info.Info.DocCount - Info.DelCount - pendingDeleteCount == count, "info.docCount={0} info.DelCount={1} pendingDeleteCount={2} count={3}", Info.Info.DocCount, Info.DelCount, pendingDeleteCount, count);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -182,7 +193,8 @@ namespace Lucene.Net.Index
// index):
public virtual SegmentReader GetMergeReader(IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
//System.out.println(" livedocs=" + rld.liveDocs);
@@ -215,25 +227,35 @@ namespace Lucene.Net.Index
mergeReader.IncRef();
return mergeReader;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void Release(SegmentReader sr)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(Info == sr.SegmentInfo);
sr.DecRef();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual bool Delete(int docID)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled)
{
Debugging.Assert(liveDocs != null);
- Debugging.Assert(Monitor.IsEntered(writer));
+ Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
Debugging.Assert(docID >= 0 && docID < liveDocs.Length, "out of bounds: docid={0} liveDocsLength={1} seg={2} docCount={3}", docID, liveDocs.Length, Info.Info.Name, Info.Info.DocCount);
Debugging.Assert(!liveDocsShared);
}
@@ -246,12 +268,17 @@ namespace Lucene.Net.Index
}
return didDelete;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// NOTE: removes callers ref
public virtual void DropReaders()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// TODO: can we somehow use IOUtils here...? problem is
// we are calling .decRef not .close)...
@@ -288,6 +315,10 @@ namespace Lucene.Net.Index
DecRef();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -297,7 +328,8 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual SegmentReader GetReadOnlyClone(IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (reader == null)
{
@@ -316,15 +348,20 @@ namespace Lucene.Net.Index
return reader;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void InitWritableLiveDocs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled)
{
- Debugging.Assert(Monitor.IsEntered(writer));
+ Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
Debugging.Assert(Info.Info.DocCount > 0);
}
//System.out.println("initWritableLivedocs seg=" + info + " liveDocs=" + liveDocs + " shared=" + shared);
@@ -347,37 +384,52 @@ namespace Lucene.Net.Index
liveDocsShared = false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual IBits LiveDocs
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
return liveDocs;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
public virtual IBits GetReadOnlyLiveDocs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
//System.out.println("getROLiveDocs seg=" + info);
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
liveDocsShared = true;
//if (liveDocs != null) {
//System.out.println(" liveCount=" + liveDocs.count());
//}
return liveDocs;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void DropChanges()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Discard (don't save) changes when we are dropping
// the reader; this is used only on the sub-readers
@@ -389,6 +441,10 @@ namespace Lucene.Net.Index
pendingDeleteCount = 0;
DropMergingUpdates();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// Commit live docs (writes new _X_N.del files) and field updates (writes new
@@ -398,9 +454,10 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual bool WriteLiveDocs(Directory dir)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
//System.out.println("rld.writeLiveDocs seg=" + info + " pendingDelCount=" + pendingDeleteCount + " numericUpdates=" + numericUpdates);
if (pendingDeleteCount == 0)
{
@@ -457,15 +514,20 @@ namespace Lucene.Net.Index
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// Writes field updates (new _X_N updates files) to the directory
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual void WriteFieldUpdates(Directory dir, DocValuesFieldUpdates.Container dvUpdates)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
//System.out.println("rld.writeFieldUpdates: seg=" + info + " numericFieldUpdates=" + numericFieldUpdates);
if (Debugging.AssertsEnabled) Debugging.Assert(dvUpdates.Any());
@@ -674,6 +736,10 @@ namespace Lucene.Net.Index
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -751,9 +817,10 @@ namespace Lucene.Net.Index
/// </summary>
internal virtual SegmentReader GetReaderForMerge(IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- if (Debugging.AssertsEnabled) Debugging.Assert(Monitor.IsEntered(writer));
+ if (Debugging.AssertsEnabled) Debugging.Assert(UninterruptableMonitor.IsEntered(writer));
// must execute these two statements as atomic operation, otherwise we
// could lose updates if e.g. another thread calls writeFieldUpdates in
// between, or the updates are applied to the obtained reader, but then
@@ -762,6 +829,10 @@ namespace Lucene.Net.Index
isMerging = true;
return GetReader(context);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -770,11 +841,16 @@ namespace Lucene.Net.Index
/// </summary>
public virtual void DropMergingUpdates()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
mergingDVUpdates.Clear();
isMerging = false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -783,10 +859,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return mergingDVUpdates;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Index/SegmentCoreReaders.cs b/src/Lucene.Net/Index/SegmentCoreReaders.cs
index 0a88cb7..dda954c 100644
--- a/src/Lucene.Net/Index/SegmentCoreReaders.cs
+++ b/src/Lucene.Net/Index/SegmentCoreReaders.cs
@@ -1,8 +1,10 @@
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
+using System.Collections;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -195,7 +197,9 @@ namespace Lucene.Net.Index
private void NotifyCoreClosedListeners(Exception th)
{
- lock (coreClosedListeners)
+ object syncRoot = ((ICollection)coreClosedListeners).SyncRoot;
+ UninterruptableMonitor.Enter(syncRoot);
+ try
{
foreach (ICoreDisposedListener listener in coreClosedListeners)
{
@@ -219,6 +223,10 @@ namespace Lucene.Net.Index
}
IOUtils.ReThrowUnchecked(th);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncRoot);
+ }
}
internal void AddCoreDisposedListener(ICoreDisposedListener listener)
diff --git a/src/Lucene.Net/Index/SegmentDocValues.cs b/src/Lucene.Net/Index/SegmentDocValues.cs
index 94b6b56..d150f4f 100644
--- a/src/Lucene.Net/Index/SegmentDocValues.cs
+++ b/src/Lucene.Net/Index/SegmentDocValues.cs
@@ -1,5 +1,6 @@
using J2N.Collections.Generic.Extensions;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -68,10 +69,15 @@ namespace Lucene.Net.Index
protected override void Release()
{
m_object.Dispose();
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
outerInstance.genDVProducers.Remove(gen);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
}
}
@@ -79,7 +85,8 @@ namespace Lucene.Net.Index
/// Returns the <see cref="DocValuesProducer"/> for the given generation. </summary>
internal DocValuesProducer GetDocValuesProducer(long? gen, SegmentCommitInfo si, IOContext context, Directory dir, DocValuesFormat dvFormat, IList<FieldInfo> infos, int termsIndexDivisor)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!genDVProducers.TryGetValue(gen, out RefCount<DocValuesProducer> dvp))
{
@@ -93,6 +100,10 @@ namespace Lucene.Net.Index
}
return dvp.Get();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -101,7 +112,8 @@ namespace Lucene.Net.Index
/// </summary>
internal void DecRef(IList<long?> dvProducersGens)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Exception t = null;
foreach (long? gen in dvProducersGens)
@@ -125,6 +137,10 @@ namespace Lucene.Net.Index
IOUtils.ReThrow(t);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/SerialMergeScheduler.cs b/src/Lucene.Net/Index/SerialMergeScheduler.cs
index fcfa922..87a2f7b 100644
--- a/src/Lucene.Net/Index/SerialMergeScheduler.cs
+++ b/src/Lucene.Net/Index/SerialMergeScheduler.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support.Threading;
using System.Runtime.CompilerServices;
namespace Lucene.Net.Index
@@ -39,7 +40,8 @@ namespace Lucene.Net.Index
[MethodImpl(MethodImplOptions.NoInlining)]
public override void Merge(IndexWriter writer, MergeTrigger trigger, bool newMergesFound) // LUCENENET NOTE: This was internal in the original, but the base class is public so there isn't much choice here
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (true)
{
@@ -51,6 +53,10 @@ namespace Lucene.Net.Index
writer.Merge(merge);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
diff --git a/src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs b/src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs
index 887030c..59812d3 100644
--- a/src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs
+++ b/src/Lucene.Net/Index/SlowCompositeReaderWrapper.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
namespace Lucene.Net.Index
@@ -109,7 +110,8 @@ namespace Lucene.Net.Index
{
EnsureOpen();
OrdinalMap map = null;
- lock (cachedOrdMaps)
+ UninterruptableMonitor.Enter(cachedOrdMaps);
+ try
{
if (!cachedOrdMaps.TryGetValue(field, out map))
{
@@ -126,6 +128,10 @@ namespace Lucene.Net.Index
return dv;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(cachedOrdMaps);
+ }
// cached ordinal map
if (FieldInfos.FieldInfo(field).DocValuesType != DocValuesType.SORTED)
{
@@ -149,7 +155,8 @@ namespace Lucene.Net.Index
{
EnsureOpen();
OrdinalMap map = null;
- lock (cachedOrdMaps)
+ UninterruptableMonitor.Enter(cachedOrdMaps);
+ try
{
if (!cachedOrdMaps.TryGetValue(field, out map))
{
@@ -166,6 +173,10 @@ namespace Lucene.Net.Index
return dv;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(cachedOrdMaps);
+ }
// cached ordinal map
if (FieldInfos.FieldInfo(field).DocValuesType != DocValuesType.SORTED_SET)
{
diff --git a/src/Lucene.Net/Index/SnapshotDeletionPolicy.cs b/src/Lucene.Net/Index/SnapshotDeletionPolicy.cs
index 44c92e9..1ead843 100644
--- a/src/Lucene.Net/Index/SnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net/Index/SnapshotDeletionPolicy.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
@@ -75,16 +76,22 @@ namespace Lucene.Net.Index
public override void OnCommit<T>(IList<T> commits)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
primary.OnCommit(WrapCommits(commits));
m_lastCommit = commits[commits.Count - 1];
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void OnInit<T>(IList<T> commits)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
initCalled = true;
primary.OnInit(WrapCommits(commits));
@@ -100,6 +107,10 @@ namespace Lucene.Net.Index
m_lastCommit = commits[commits.Count - 1];
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -109,11 +120,16 @@ namespace Lucene.Net.Index
/// the commit previously returned by <see cref="Snapshot()"/> </param>
public virtual void Release(IndexCommit commit)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
long gen = commit.Generation;
ReleaseGen(gen);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -147,7 +163,8 @@ namespace Lucene.Net.Index
/// Increments the refCount for this <see cref="IndexCommit"/>. </summary>
protected internal virtual void IncRef(IndexCommit ic)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
long gen = ic.Generation;
int refCountInt;
@@ -162,6 +179,10 @@ namespace Lucene.Net.Index
}
m_refCounts[gen] = refCountInt + 1;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -182,7 +203,8 @@ namespace Lucene.Net.Index
/// <returns> the <see cref="IndexCommit"/> that was snapshotted. </returns>
public virtual IndexCommit Snapshot()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!initCalled)
{
@@ -198,16 +220,25 @@ namespace Lucene.Net.Index
return m_lastCommit;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
/// Returns all <see cref="IndexCommit"/>s held by at least one snapshot. </summary>
public virtual IList<IndexCommit> GetSnapshots()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return new List<IndexCommit>(m_indexCommits.Values);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -216,7 +247,8 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int total = 0;
foreach (var refCount in m_refCounts.Values)
@@ -226,6 +258,10 @@ namespace Lucene.Net.Index
return total;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -236,15 +272,21 @@ namespace Lucene.Net.Index
/// </summary>
public virtual IndexCommit GetIndexCommit(long gen)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return m_indexCommits[gen];
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override object Clone()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
SnapshotDeletionPolicy other = (SnapshotDeletionPolicy)base.Clone();
other.primary = (IndexDeletionPolicy)this.primary.Clone();
@@ -253,6 +295,10 @@ namespace Lucene.Net.Index
other.m_indexCommits = new Dictionary<long?, IndexCommit>(m_indexCommits);
return other;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -299,7 +345,8 @@ namespace Lucene.Net.Index
public override void Delete()
{
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
// Suppress the delete request if this commit point is
// currently snapshotted.
@@ -308,6 +355,10 @@ namespace Lucene.Net.Index
m_cp.Delete();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
}
public override Directory Directory => m_cp.Directory;
diff --git a/src/Lucene.Net/Index/StoredFieldsProcessor.cs b/src/Lucene.Net/Index/StoredFieldsProcessor.cs
index 4cbb401..342562b 100644
--- a/src/Lucene.Net/Index/StoredFieldsProcessor.cs
+++ b/src/Lucene.Net/Index/StoredFieldsProcessor.cs
@@ -1,5 +1,6 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Runtime.CompilerServices;
@@ -99,7 +100,8 @@ namespace Lucene.Net.Index
private void InitFieldsWriter(IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (fieldsWriter == null)
{
@@ -107,6 +109,10 @@ namespace Lucene.Net.Index
lastDocID = 0;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
[MethodImpl(MethodImplOptions.NoInlining)]
diff --git a/src/Lucene.Net/Index/TermsEnum.cs b/src/Lucene.Net/Index/TermsEnum.cs
index c185b93..bb760e1 100644
--- a/src/Lucene.Net/Index/TermsEnum.cs
+++ b/src/Lucene.Net/Index/TermsEnum.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Util;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -336,10 +337,15 @@ namespace Lucene.Net.Index
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return base.Attributes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Search/CachingWrapperFilter.cs b/src/Lucene.Net/Search/CachingWrapperFilter.cs
index 22600eb..1c170b5 100644
--- a/src/Lucene.Net/Search/CachingWrapperFilter.cs
+++ b/src/Lucene.Net/Search/CachingWrapperFilter.cs
@@ -1,5 +1,6 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@@ -171,7 +172,8 @@ namespace Lucene.Net.Search
{
// Sync only to pull the current set of values:
List<DocIdSet> docIdSets;
- lock (_cache)
+ UninterruptableMonitor.Enter(_cache);
+ try
{
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
docIdSets = new List<DocIdSet>();
@@ -181,6 +183,10 @@ namespace Lucene.Net.Search
docIdSets = new List<DocIdSet>(_cache.Values);
#endif
}
+ finally
+ {
+ UninterruptableMonitor.Exit(_cache);
+ }
long total = 0;
foreach (DocIdSet dis in docIdSets)
diff --git a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
index 954c018..b1f8020 100644
--- a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
@@ -1,5 +1,6 @@
using J2N;
using J2N.Threading;
+using Lucene.Net.Support.Threading;
using System;
using System.Threading;
@@ -103,12 +104,17 @@ namespace Lucene.Net.Search
private void RefreshDone()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// if we're finishing, , make it out so that all waiting search threads will return
searchingGen = finish ? long.MaxValue : refreshStartGen;
available.Set();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
reopenCond.Reset();
}
@@ -192,7 +198,9 @@ namespace Lucene.Net.Search
{
throw new ArgumentException("targetGen=" + targetGen + " was never returned by the ReferenceManager instance (current gen=" + curGen + ")");
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
+ {
if (targetGen <= searchingGen)
return true;
else
@@ -201,6 +209,11 @@ namespace Lucene.Net.Search
reopenCond.Set();
available.Reset();
}
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
long startMS = Time.NanoTime() / 1000000;
@@ -239,8 +252,15 @@ namespace Lucene.Net.Search
{
bool hasWaiting;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
+ {
hasWaiting = waitingGen > searchingGen;
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
long nextReopenStartNS = lastReopenStartNS + (hasWaiting ? targetMinStaleNS : targetMaxStaleNS);
long sleepNS = nextReopenStartNS - Time.NanoTime();
diff --git a/src/Lucene.Net/Search/FieldCacheImpl.cs b/src/Lucene.Net/Search/FieldCacheImpl.cs
index 8a64830..15069f1 100644
--- a/src/Lucene.Net/Search/FieldCacheImpl.cs
+++ b/src/Lucene.Net/Search/FieldCacheImpl.cs
@@ -3,6 +3,7 @@ using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Support;
using Lucene.Net.Support.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -96,15 +97,21 @@ namespace Lucene.Net.Search
public virtual void PurgeAllCaches()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Init();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void PurgeByCacheKey(object coreCacheKey)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// LUCENENET specific - removed unnecessary Dictionary and loop
caches_typeof_sbyte.PurgeByCacheKey(coreCacheKey);
@@ -118,13 +125,18 @@ namespace Lucene.Net.Search
caches_typeof_DocTermOrds.PurgeByCacheKey(coreCacheKey);
caches_typeof_DocsWithFieldCache.PurgeByCacheKey(coreCacheKey);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual FieldCache.CacheEntry[] GetCacheEntries()
{
// LUCENENET specific - instantiate/ToArray() outside of lock to improve performance
IList<FieldCache.CacheEntry> result = new List<FieldCache.CacheEntry>(17);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// LUCENENET specific - refactored to use generic CacheKey to reduce casting and removed unnecessary Dictionary/loop
AddCacheEntries(result, typeof(sbyte), caches_typeof_sbyte);
@@ -138,12 +150,17 @@ namespace Lucene.Net.Search
AddCacheEntries(result, typeof(DocTermOrds), caches_typeof_DocTermOrds);
AddCacheEntries(result, typeof(DocsWithFieldCache), caches_typeof_DocsWithFieldCache);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
return result.ToArray();
}
private void AddCacheEntries<TKey, TValue>(IList<FieldCache.CacheEntry> result, Type cacheType, Cache<TKey, TValue> cache) where TKey : CacheKey
{
- lock (cache.readerCache)
+ UninterruptableMonitor.Enter(cache.readerCache);
+ try
{
foreach (var readerCacheEntry in cache.readerCache)
{
@@ -160,6 +177,10 @@ namespace Lucene.Net.Search
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(cache.readerCache);
+ }
}
// per-segment fieldcaches don't purge until the shared core closes.
@@ -245,8 +266,15 @@ namespace Lucene.Net.Search
/// Remove this reader from the cache, if present. </summary>
public virtual void PurgeByCacheKey(object coreCacheKey)
{
- lock (readerCache)
+ UninterruptableMonitor.Enter(readerCache);
+ try
+ {
readerCache.Remove(coreCacheKey);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(readerCache);
+ }
}
/// <summary>
@@ -257,7 +285,8 @@ namespace Lucene.Net.Search
{
IDictionary<TKey, object> innerCache;
object readerKey = reader.CoreCacheKey;
- lock (readerCache)
+ UninterruptableMonitor.Enter(readerCache);
+ try
{
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
@@ -286,6 +315,10 @@ namespace Lucene.Net.Search
innerCache[key] = value;
// else if another thread beat us to it, leave the current value
}
+ finally
+ {
+ UninterruptableMonitor.Exit(readerCache);
+ }
}
public virtual TValue Get(AtomicReader reader, TKey key, bool setDocsWithField)
@@ -293,7 +326,8 @@ namespace Lucene.Net.Search
IDictionary<TKey, object> innerCache;
object value = null;
object readerKey = reader.CoreCacheKey;
- lock (readerCache)
+ UninterruptableMonitor.Enter(readerCache);
+ try
{
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
innerCache = readerCache.GetValue(readerKey, (readerKey) =>
@@ -327,17 +361,27 @@ namespace Lucene.Net.Search
innerCache[key] = value = new FieldCache.CreationPlaceholder<TValue>();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(readerCache);
+ }
if (value is FieldCache.CreationPlaceholder<TValue> progress)
{
- lock (value)
+ UninterruptableMonitor.Enter(value);
+ try
{
if (progress.Value is null)
{
progress.Value = CreateValue(reader, key, setDocsWithField);
- lock (readerCache)
+ UninterruptableMonitor.Enter(readerCache);
+ try
{
innerCache[key] = progress.Value;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(readerCache);
+ }
// Only check if key.custom (the parser) is
// non-null; else, we check twice for a single
// call to FieldCache.getXXX
@@ -352,6 +396,10 @@ namespace Lucene.Net.Search
}
return progress.Value;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(value);
+ }
}
return (TValue)value;
}
diff --git a/src/Lucene.Net/Search/ReferenceManager.cs b/src/Lucene.Net/Search/ReferenceManager.cs
index 37bd91e..c6f66df 100644
--- a/src/Lucene.Net/Search/ReferenceManager.cs
+++ b/src/Lucene.Net/Search/ReferenceManager.cs
@@ -68,13 +68,18 @@ namespace Lucene.Net.Search
private void SwapReference(G newReference)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
G oldReference = current;
current = newReference;
Release(oldReference);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -173,7 +178,8 @@ namespace Lucene.Net.Search
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (current != null)
{
@@ -183,6 +189,10 @@ namespace Lucene.Net.Search
SwapReference(null);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net/Search/SearcherLifetimeManager.cs b/src/Lucene.Net/Search/SearcherLifetimeManager.cs
index a62eb41..36348a5 100644
--- a/src/Lucene.Net/Search/SearcherLifetimeManager.cs
+++ b/src/Lucene.Net/Search/SearcherLifetimeManager.cs
@@ -1,4 +1,5 @@
using J2N;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -127,10 +128,15 @@ namespace Lucene.Net.Search
public void Dispose()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Searcher.IndexReader.DecRef();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -264,7 +270,8 @@ namespace Lucene.Net.Search
/// </summary>
public virtual void Prune(IPruner pruner)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Cannot just pass searchers.values() to ArrayList ctor
// (not thread-safe since the values can change while
@@ -299,6 +306,10 @@ namespace Lucene.Net.Search
lastRecordTimeSec = tracker.RecordTimeSec;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -330,7 +341,8 @@ namespace Lucene.Net.Search
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
_closed = true;
IList<SearcherTracker> toClose = new List<SearcherTracker>(_searchers.Values.Select(item => item.Value));
@@ -350,6 +362,10 @@ namespace Lucene.Net.Search
throw IllegalStateException.Create("another thread called record while this SearcherLifetimeManager instance was being disposed; not all searchers were disposed");
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net/Search/TimeLimitingCollector.cs b/src/Lucene.Net/Search/TimeLimitingCollector.cs
index 4549503..23477cd 100644
--- a/src/Lucene.Net/Search/TimeLimitingCollector.cs
+++ b/src/Lucene.Net/Search/TimeLimitingCollector.cs
@@ -1,4 +1,5 @@
using J2N.Threading;
+using Lucene.Net.Support.Threading;
using System;
#if FEATURE_SERIALIZABLE_EXCEPTIONS
using System.Runtime.Serialization;
diff --git a/src/Lucene.Net/Store/CompoundFileDirectory.cs b/src/Lucene.Net/Store/CompoundFileDirectory.cs
index 5765045..92dca31 100644
--- a/src/Lucene.Net/Store/CompoundFileDirectory.cs
+++ b/src/Lucene.Net/Store/CompoundFileDirectory.cs
@@ -2,6 +2,7 @@
using J2N.Numerics;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -285,7 +286,8 @@ namespace Lucene.Net.Store
protected override void Dispose(bool disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (disposing)
{
@@ -306,11 +308,16 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override IndexInput OpenInput(string name, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
if (Debugging.AssertsEnabled) Debugging.Assert(!openForWrite);
@@ -323,6 +330,10 @@ namespace Lucene.Net.Store
}
return handle.OpenSlice(name, entry.Offset, entry.Length);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net/Store/CompoundFileWriter.cs b/src/Lucene.Net/Store/CompoundFileWriter.cs
index 583d9d2..63f01f9 100644
--- a/src/Lucene.Net/Store/CompoundFileWriter.cs
+++ b/src/Lucene.Net/Store/CompoundFileWriter.cs
@@ -1,6 +1,7 @@
using J2N.Collections.Generic.Extensions;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -100,7 +101,8 @@ namespace Lucene.Net.Store
private IndexOutput GetOutput()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (dataOut == null)
{
@@ -121,6 +123,10 @@ namespace Lucene.Net.Store
}
return dataOut;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net/Store/Lock.cs b/src/Lucene.Net/Store/Lock.cs
index 0f9d167..5613439 100644
--- a/src/Lucene.Net/Store/Lock.cs
+++ b/src/Lucene.Net/Store/Lock.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support.Threading;
+using System;
using System.IO;
using System.Threading;
diff --git a/src/Lucene.Net/Store/LockVerifyServer.cs b/src/Lucene.Net/Store/LockVerifyServer.cs
index edfa6f0..af4c47c 100644
--- a/src/Lucene.Net/Store/LockVerifyServer.cs
+++ b/src/Lucene.Net/Store/LockVerifyServer.cs
@@ -1,4 +1,5 @@
using J2N.Threading;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Globalization;
@@ -136,7 +137,8 @@ namespace Lucene.Net.Store
return; // closed
}
- lock (localLock)
+ UninterruptableMonitor.Enter(localLock);
+ try
{
int currentLock = lockedID[0];
if (currentLock == -2)
@@ -171,6 +173,10 @@ namespace Lucene.Net.Store
intWriter.Write((byte)command);
stream.Flush();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(localLock);
+ }
}
}
catch (Exception e) when (e.IsRuntimeException() || e.IsError())
diff --git a/src/Lucene.Net/Store/NRTCachingDirectory.cs b/src/Lucene.Net/Store/NRTCachingDirectory.cs
index ba50abf..94e9c5f 100644
--- a/src/Lucene.Net/Store/NRTCachingDirectory.cs
+++ b/src/Lucene.Net/Store/NRTCachingDirectory.cs
@@ -1,4 +1,5 @@
using J2N.Collections.Generic.Extensions;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -120,7 +121,8 @@ namespace Lucene.Net.Store
public override string[] ListAll()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
ISet<string> files = new JCG.HashSet<string>();
foreach (string f in cache.ListAll())
@@ -152,6 +154,10 @@ namespace Lucene.Net.Store
}
return files.ToArray();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -166,15 +172,21 @@ namespace Lucene.Net.Store
[Obsolete("this method will be removed in 5.0")]
public override bool FileExists(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return cache.FileExists(name) || @delegate.FileExists(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void DeleteFile(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (VERBOSE)
{
@@ -191,11 +203,16 @@ namespace Lucene.Net.Store
@delegate.DeleteFile(name);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override long FileLength(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
#pragma warning disable 612, 618
if (cache.FileExists(name))
@@ -208,6 +225,10 @@ namespace Lucene.Net.Store
return @delegate.FileLength(name);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual string[] ListCachedFiles()
@@ -266,7 +287,8 @@ namespace Lucene.Net.Store
public override IndexInput OpenInput(string name, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (VERBOSE)
{
@@ -287,11 +309,16 @@ namespace Lucene.Net.Store
return @delegate.OpenInput(name, context);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override IndexInputSlicer CreateSlicer(string name, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
EnsureOpen();
if (VERBOSE)
@@ -313,6 +340,10 @@ namespace Lucene.Net.Store
return @delegate.CreateSlicer(name, context);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -364,7 +395,8 @@ namespace Lucene.Net.Store
{
// Only let one thread uncache at a time; this only
// happens during commit() or close():
- lock (uncacheLock)
+ UninterruptableMonitor.Enter(uncacheLock);
+ try
{
if (VERBOSE)
{
@@ -391,12 +423,21 @@ namespace Lucene.Net.Store
}
// Lock order: uncacheLock -> this
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// Must sync here because other sync methods have
// if (cache.fileExists(name)) { ... } else { ... }:
cache.DeleteFile(fileName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(uncacheLock);
}
}
}
diff --git a/src/Lucene.Net/Store/NativeFSLockFactory.cs b/src/Lucene.Net/Store/NativeFSLockFactory.cs
index 484d889..374deee 100644
--- a/src/Lucene.Net/Store/NativeFSLockFactory.cs
+++ b/src/Lucene.Net/Store/NativeFSLockFactory.cs
@@ -3,6 +3,7 @@ using Lucene.Net.Util;
using System;
using System.IO;
using System.Collections.Generic;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Store
{
@@ -197,9 +198,16 @@ namespace Lucene.Net.Store
{
var path = GetCanonicalPathOfLockFile(lockName);
Lock l;
- lock (_locks)
+ UninterruptableMonitor.Enter(_locks);
+ try
+ {
if (!_locks.TryGetValue(path, out l))
_locks.Add(path, l = NewLock(path));
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(_locks);
+ }
return l;
}
@@ -225,12 +233,19 @@ namespace Lucene.Net.Store
var path = GetCanonicalPathOfLockFile(lockName);
// this is the reason why we can't use ConcurrentDictionary: we need the removal and disposal of the lock to be atomic
// otherwise it may clash with MakeLock making a lock and ClearLock disposing of it in another thread.
- lock (_locks)
+ UninterruptableMonitor.Enter(_locks);
+ try
+ {
if (_locks.TryGetValue(path, out Lock l))
{
_locks.Remove(path);
l.Dispose();
}
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(_locks);
+ }
}
}
@@ -259,7 +274,8 @@ namespace Lucene.Net.Store
public override bool Obtain()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
FailureReason = null;
@@ -317,20 +333,32 @@ namespace Lucene.Net.Store
return channel != null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// whether or not we have created a file, we need to remove
// the lock instance from the dictionary that tracks them.
try
{
- lock (NativeFSLockFactory._locks)
+ UninterruptableMonitor.Enter(NativeFSLockFactory._locks);
+ try
+ {
NativeFSLockFactory._locks.Remove(path);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(NativeFSLockFactory._locks);
+ }
}
finally
{
@@ -361,12 +389,17 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
public override bool IsLocked()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// The test for is isLocked is not directly possible with native file locks:
@@ -400,6 +433,10 @@ namespace Lucene.Net.Store
return false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override string ToString()
@@ -465,7 +502,8 @@ namespace Lucene.Net.Store
public override bool Obtain()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
FailureReason = null;
@@ -497,20 +535,32 @@ namespace Lucene.Net.Store
}
return channel != null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// whether or not we have created a file, we need to remove
// the lock instance from the dictionary that tracks them.
try
{
- lock (NativeFSLockFactory._locks)
+ UninterruptableMonitor.Enter(NativeFSLockFactory._locks);
+ try
+ {
NativeFSLockFactory._locks.Remove(path);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(NativeFSLockFactory._locks);
+ }
}
finally
{
@@ -527,12 +577,17 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
public override bool IsLocked()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// First a shortcut, if a lock reference in this instance is available
if (channel != null)
@@ -557,6 +612,10 @@ namespace Lucene.Net.Store
return false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override string ToString()
@@ -617,7 +676,8 @@ namespace Lucene.Net.Store
public override bool Obtain()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
FailureReason = null;
@@ -662,20 +722,32 @@ namespace Lucene.Net.Store
}
return channel != null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// whether or not we have created a file, we need to remove
// the lock instance from the dictionary that tracks them.
try
{
- lock (NativeFSLockFactory._locks)
+ UninterruptableMonitor.Enter(NativeFSLockFactory._locks);
+ try
+ {
NativeFSLockFactory._locks.Remove(path);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(NativeFSLockFactory._locks);
+ }
}
finally
{
@@ -700,12 +772,17 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
public override bool IsLocked()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// First a shortcut, if a lock reference in this instance is available
if (channel != null)
@@ -734,6 +811,10 @@ namespace Lucene.Net.Store
return false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override string ToString()
diff --git a/src/Lucene.Net/Store/RAMFile.cs b/src/Lucene.Net/Store/RAMFile.cs
index 1da3b5e..80d3bb9 100644
--- a/src/Lucene.Net/Store/RAMFile.cs
+++ b/src/Lucene.Net/Store/RAMFile.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
namespace Lucene.Net.Store
@@ -50,28 +51,43 @@ namespace Lucene.Net.Store
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return length;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
set
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
this.length = value;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
protected internal byte[] AddBuffer(int size)
{
byte[] buffer = NewBuffer(size);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
m_buffers.Add(buffer);
m_sizeInBytes += size;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if (directory != null)
{
@@ -82,20 +98,30 @@ namespace Lucene.Net.Store
protected internal byte[] GetBuffer(int index)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return m_buffers[index];
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected internal int NumBuffers
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return m_buffers.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -111,10 +137,15 @@ namespace Lucene.Net.Store
public virtual long GetSizeInBytes()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return m_sizeInBytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Store/RateLimiter.cs b/src/Lucene.Net/Store/RateLimiter.cs
index 61e2339..9e97211 100644
--- a/src/Lucene.Net/Store/RateLimiter.cs
+++ b/src/Lucene.Net/Store/RateLimiter.cs
@@ -1,4 +1,5 @@
using J2N;
+using Lucene.Net.Support.Threading;
using System;
using System.Threading;
diff --git a/src/Lucene.Net/Store/SimpleFSDirectory.cs b/src/Lucene.Net/Store/SimpleFSDirectory.cs
index e0a6e2e..8247314 100644
--- a/src/Lucene.Net/Store/SimpleFSDirectory.cs
+++ b/src/Lucene.Net/Store/SimpleFSDirectory.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
@@ -205,7 +206,8 @@ namespace Lucene.Net.Store
/// <see cref="IndexInput"/> methods </summary>
protected override void ReadInternal(byte[] b, int offset, int len)
{
- lock (m_file)
+ UninterruptableMonitor.Enter(m_file);
+ try
{
long position = m_off + Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
m_file.Seek(position, SeekOrigin.Begin);
@@ -242,6 +244,10 @@ namespace Lucene.Net.Store
throw new IOException(ioe.Message + ": " + this, ioe);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_file);
+ }
}
protected override void SeekInternal(long position)
diff --git a/src/Lucene.Net/Store/SingleInstanceLockFactory.cs b/src/Lucene.Net/Store/SingleInstanceLockFactory.cs
index e432340..f78bc0b 100644
--- a/src/Lucene.Net/Store/SingleInstanceLockFactory.cs
+++ b/src/Lucene.Net/Store/SingleInstanceLockFactory.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -43,13 +44,18 @@ namespace Lucene.Net.Store
public override void ClearLock(string lockName)
{
- lock (locks)
+ UninterruptableMonitor.Enter(locks);
+ try
{
if (locks.Contains(lockName))
{
locks.Remove(lockName);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(locks);
+ }
}
}
@@ -66,29 +72,44 @@ namespace Lucene.Net.Store
public override bool Obtain()
{
- lock (locks)
+ UninterruptableMonitor.Enter(locks);
+ try
{
return locks.Add(lockName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(locks);
+ }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (locks)
+ UninterruptableMonitor.Enter(locks);
+ try
{
locks.Remove(lockName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(locks);
+ }
}
}
public override bool IsLocked()
{
- lock (locks)
+ UninterruptableMonitor.Enter(locks);
+ try
{
return locks.Contains(lockName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(locks);
+ }
}
public override string ToString()
diff --git a/src/Lucene.Net/Store/VerifyingLockFactory.cs b/src/Lucene.Net/Store/VerifyingLockFactory.cs
index bf9b71b..eff9f59 100644
--- a/src/Lucene.Net/Store/VerifyingLockFactory.cs
+++ b/src/Lucene.Net/Store/VerifyingLockFactory.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
@@ -66,7 +67,8 @@ namespace Lucene.Net.Store
public override bool Obtain()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
bool obtained = @lock.Obtain();
if (obtained)
@@ -75,21 +77,31 @@ namespace Lucene.Net.Store
}
return obtained;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override bool IsLocked()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return @lock.IsLocked();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (IsLocked())
{
@@ -97,6 +109,10 @@ namespace Lucene.Net.Store
@lock.Dispose();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
@@ -114,18 +130,28 @@ namespace Lucene.Net.Store
public override Lock MakeLock(string lockName)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return new CheckedLock(this, lf.MakeLock(lockName));
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void ClearLock(string lockName)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
lf.ClearLock(lockName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
index c4e74a0..c1e66e7 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Util;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.Reflection;
@@ -218,10 +219,15 @@ namespace Lucene.Net.Codecs
private void PutCodecTypeImpl(Type codec)
{
string name = GetServiceName(codec);
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
codecNameToTypeMap[name] = codec;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -232,11 +238,16 @@ namespace Lucene.Net.Codecs
public virtual Codec GetCodec(string name)
{
EnsureInitialized(); // Safety in case a subclass doesn't call it
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
Type codecType = GetCodecType(name);
return GetCodec(codecType);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -250,7 +261,8 @@ namespace Lucene.Net.Codecs
throw new ArgumentNullException(nameof(type));
if (!codecInstanceCache.TryGetValue(type, out Codec instance))
{
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
if (!codecInstanceCache.TryGetValue(type, out instance))
{
@@ -258,6 +270,10 @@ namespace Lucene.Net.Codecs
codecInstanceCache[type] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
return instance;
diff --git a/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
index e7e1b4f..b96becf 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Util;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.Reflection;
@@ -214,10 +215,15 @@ namespace Lucene.Net.Codecs
private void PutDocValuesFormatTypeImpl(Type docValuesFormat)
{
string name = GetServiceName(docValuesFormat);
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
docValuesFormatNameToTypeMap[name] = docValuesFormat;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -228,11 +234,16 @@ namespace Lucene.Net.Codecs
public virtual DocValuesFormat GetDocValuesFormat(string name)
{
EnsureInitialized(); // Safety in case a subclass doesn't call it
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
Type codecType = GetDocValuesFormatType(name);
return GetDocValuesFormat(codecType);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -246,7 +257,8 @@ namespace Lucene.Net.Codecs
throw new ArgumentNullException(nameof(type));
if (!docValuesFormatInstanceCache.TryGetValue(type, out DocValuesFormat instance))
{
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
if (!docValuesFormatInstanceCache.TryGetValue(type, out instance))
{
@@ -254,6 +266,10 @@ namespace Lucene.Net.Codecs
docValuesFormatInstanceCache[type] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
return instance;
diff --git a/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
index 8da5aeb..40637f2 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Util;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.Reflection;
@@ -214,10 +215,15 @@ namespace Lucene.Net.Codecs
private void PutPostingsFormatTypeImpl(Type postingsFormat)
{
string name = GetServiceName(postingsFormat);
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
postingsFormatNameToTypeMap[name] = postingsFormat;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -228,11 +234,16 @@ namespace Lucene.Net.Codecs
public virtual PostingsFormat GetPostingsFormat(string name)
{
EnsureInitialized(); // Safety in case a subclass doesn't call it
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
Type codecType = GetPostingsFormatType(name);
return GetPostingsFormat(codecType);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
/// <summary>
@@ -246,7 +257,8 @@ namespace Lucene.Net.Codecs
throw new ArgumentNullException(nameof(type));
if (!postingsFormatInstanceCache.TryGetValue(type, out PostingsFormat instance))
{
- lock (m_initializationLock)
+ UninterruptableMonitor.Enter(m_initializationLock);
+ try
{
if (!postingsFormatInstanceCache.TryGetValue(type, out instance))
{
@@ -254,6 +266,10 @@ namespace Lucene.Net.Codecs
postingsFormatInstanceCache[type] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_initializationLock);
+ }
}
return instance;
diff --git a/src/Lucene.Net/Support/ConcurrentHashSet.cs b/src/Lucene.Net/Support/ConcurrentHashSet.cs
index c728b39..57f3c52 100644
--- a/src/Lucene.Net/Support/ConcurrentHashSet.cs
+++ b/src/Lucene.Net/Support/ConcurrentHashSet.cs
@@ -24,6 +24,7 @@ SOFTWARE.
*/
+using Lucene.Net.Support.Threading;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -352,7 +353,9 @@ namespace Lucene.Net.Support
GetBucketAndLockNo(hashcode, out int bucketNo, out int lockNo, tables.Buckets.Length, tables.Locks.Length);
- lock (tables.Locks[lockNo])
+ object syncRoot = tables.Locks[lockNo];
+ UninterruptableMonitor.Enter(syncRoot);
+ try
{
// If the table just got resized, we may not be holding the right lock, and must retry.
// This should be a rare occurrence.
@@ -383,6 +386,10 @@ namespace Lucene.Net.Support
previous = current;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncRoot);
+ }
return false;
}
@@ -478,7 +485,7 @@ namespace Lucene.Net.Support
try
{
if (acquireLock)
- Monitor.Enter(tables.Locks[lockNo], ref lockTaken);
+ UninterruptableMonitor.Enter(tables.Locks[lockNo], ref lockTaken);
// If the table just got resized, we may not be holding the right lock, and must retry.
// This should be a rare occurrence.
@@ -519,7 +526,7 @@ namespace Lucene.Net.Support
finally
{
if (lockTaken)
- Monitor.Exit(tables.Locks[lockNo]);
+ UninterruptableMonitor.Exit(tables.Locks[lockNo]);
}
//
@@ -709,7 +716,7 @@ namespace Lucene.Net.Support
var lockTaken = false;
try
{
- Monitor.Enter(locks[i], ref lockTaken);
+ UninterruptableMonitor.Enter(locks[i], ref lockTaken);
}
finally
{
@@ -727,7 +734,7 @@ namespace Lucene.Net.Support
for (var i = fromInclusive; i < toExclusive; i++)
{
- Monitor.Exit(_tables.Locks[i]);
+ UninterruptableMonitor.Exit(_tables.Locks[i]);
}
}
diff --git a/src/Lucene.Net/Support/ConcurrentSet.cs b/src/Lucene.Net/Support/ConcurrentSet.cs
index 5619801..eaba680 100644
--- a/src/Lucene.Net/Support/ConcurrentSet.cs
+++ b/src/Lucene.Net/Support/ConcurrentSet.cs
@@ -1,4 +1,5 @@
using J2N.Text;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -42,92 +43,197 @@ namespace Lucene.Net.Support
public bool Add(T item)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.Add(item);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void ExceptWith(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.ExceptWith(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void IntersectWith(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.IntersectWith(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool IsProperSubsetOf(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.IsProperSubsetOf(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool IsProperSupersetOf(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.IsProperSupersetOf(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool IsSubsetOf(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.IsSubsetOf(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool IsSupersetOf(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.IsSupersetOf(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool Overlaps(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.Overlaps(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool SetEquals(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.SetEquals(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void SymmetricExceptWith(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.SymmetricExceptWith(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void UnionWith(IEnumerable<T> other)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.UnionWith(other);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
void ICollection<T>.Add(T item)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.Add(item);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void Clear()
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.Clear();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public bool Contains(T item)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.Contains(item);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public void CopyTo(T[] array, int arrayIndex)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
set.CopyTo(array, arrayIndex);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
void ICollection.CopyTo(Array array, int index)
@@ -167,11 +273,16 @@ namespace Lucene.Net.Support
try
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
{
foreach (var item in set)
objects[index++] = item;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
catch (ArrayTypeMismatchException)
{
@@ -185,8 +296,15 @@ namespace Lucene.Net.Support
{
get
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.Count;
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
}
@@ -210,18 +328,30 @@ namespace Lucene.Net.Support
public bool Remove(T item)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return set.Remove(item);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
public IEnumerator<T> GetEnumerator()
{
// Make a copy of the contents since enumeration is lazy and not thread-safe
T[] array = new T[set.Count];
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
{
set.CopyTo(array, 0);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
return ((IEnumerable<T>)array).GetEnumerator();
}
@@ -244,8 +374,15 @@ namespace Lucene.Net.Support
/// <exception cref="ArgumentNullException">If <paramref name="comparer"/> is <c>null</c>.</exception>
public bool Equals(object? other, IEqualityComparer comparer)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return JCG.SetEqualityComparer<T>.Equals(set, other, comparer);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
/// <summary>
@@ -257,8 +394,15 @@ namespace Lucene.Net.Support
/// <returns>A hash code representing the current set.</returns>
public int GetHashCode(IEqualityComparer comparer)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
+ {
return JCG.SetEqualityComparer<T>.GetHashCode(set, comparer);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
/// <summary>
@@ -301,13 +445,18 @@ namespace Lucene.Net.Support
/// </exception>
public string ToString(string? format, IFormatProvider? formatProvider)
{
- lock (SyncRoot)
+ UninterruptableMonitor.Enter(SyncRoot);
+ try
{
if (set is IFormattable formattable)
return formattable.ToString(format ?? "{0}", formatProvider);
return string.Format(formatProvider, format ?? "{0}", set);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(SyncRoot);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net/Support/IO/StreamExtensions.cs b/src/Lucene.Net/Support/IO/StreamExtensions.cs
index f5b9fc0..e74c3d7 100644
--- a/src/Lucene.Net/Support/IO/StreamExtensions.cs
+++ b/src/Lucene.Net/Support/IO/StreamExtensions.cs
@@ -1,4 +1,5 @@
using J2N.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
@@ -81,7 +82,8 @@ namespace Lucene.Net.Support.IO
return 0;
int read = 0;
- lock (readLock)
+ UninterruptableMonitor.Enter(readLock);
+ try
{
long originalPosition = stream.Position;
stream.Seek(position, SeekOrigin.Begin);
@@ -111,6 +113,10 @@ namespace Lucene.Net.Support.IO
// of the stream, so we return it as it was originally.
stream.Seek(originalPosition, SeekOrigin.Begin);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(readLock);
+ }
return read;
}
diff --git a/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs b/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs
index 3e26cf5..ce807e4 100644
--- a/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs
+++ b/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs
@@ -87,8 +87,9 @@ namespace Lucene.Net.Support.Threading
protected sealed override void QueueTask(Task task)
{
// Add the task to the list of tasks to be processed. If there aren't enough
- // delegates currently queued or running to process tasks, schedule another.
- lock (_tasks)
+ // delegates currently queued or running to process tasks, schedule another.
+ UninterruptableMonitor.Enter(_tasks);
+ try
{
_tasks.AddLast(task);
if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
@@ -97,6 +98,10 @@ namespace Lucene.Net.Support.Threading
NotifyThreadPoolOfPendingWork();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(_tasks);
+ }
}
// Inform the ThreadPool that there's work to be executed for this scheduler.
@@ -118,7 +123,8 @@ namespace Lucene.Net.Support.Threading
while (true)
{
Task item;
- lock (_tasks)
+ UninterruptableMonitor.Enter(_tasks);
+ try
{
// When there are no more items to be processed,
// note that we're done processing, and get out.
@@ -132,6 +138,10 @@ namespace Lucene.Net.Support.Threading
item = _tasks.First.Value;
_tasks.Remove(item);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(_tasks);
+ }
// Execute the task we pulled out of the queue
base.TryExecuteTask(item);
@@ -162,7 +172,15 @@ namespace Lucene.Net.Support.Threading
// Attempt to remove a previously scheduled task from the scheduler.
protected sealed override bool TryDequeue(Task task)
{
- lock (_tasks) return _tasks.Remove(task);
+ UninterruptableMonitor.Enter(_tasks);
+ try
+ {
+ return _tasks.Remove(task);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(_tasks);
+ }
}
// Gets the maximum concurrency level supported by this scheduler.
@@ -174,13 +192,13 @@ namespace Lucene.Net.Support.Threading
bool lockTaken = false;
try
{
- Monitor.TryEnter(_tasks, ref lockTaken);
+ UninterruptableMonitor.TryEnter(_tasks, ref lockTaken);
if (lockTaken) return _tasks;
else throw new NotSupportedException();
}
finally
{
- if (lockTaken) Monitor.Exit(_tasks);
+ if (lockTaken) UninterruptableMonitor.Exit(_tasks);
}
}
}
diff --git a/src/Lucene.Net/Support/Threading/ReentrantLock.cs b/src/Lucene.Net/Support/Threading/ReentrantLock.cs
index 702a091..dd1359b 100644
--- a/src/Lucene.Net/Support/Threading/ReentrantLock.cs
+++ b/src/Lucene.Net/Support/Threading/ReentrantLock.cs
@@ -36,20 +36,20 @@ namespace Lucene.Net.Support.Threading
// we enter the lock, then we immediately decrement it because that thread is no longer in the queue.
// Due to race conditions, the queue length is an estimate only.
Interlocked.Increment(ref _queueLength);
- Monitor.Enter(_lock);
+ UninterruptableMonitor.Enter(_lock);
Interlocked.Decrement(ref _queueLength);
}
// .NET Port: mimic ReentrantLock -- Monitor is re-entrant
public void Unlock()
{
- Monitor.Exit(_lock);
+ UninterruptableMonitor.Exit(_lock);
}
public bool TryLock()
{
Interlocked.Increment(ref _queueLength);
- bool success = Monitor.TryEnter(_lock);
+ bool success = UninterruptableMonitor.TryEnter(_lock);
Interlocked.Decrement(ref _queueLength);
return success;
@@ -69,6 +69,6 @@ namespace Lucene.Net.Support.Threading
public bool HasQueuedThreads => _queueLength > 0;
- public bool IsHeldByCurrentThread => Monitor.IsEntered(_lock);
+ public bool IsHeldByCurrentThread => UninterruptableMonitor.IsEntered(_lock);
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net/Util/AttributeSource.cs b/src/Lucene.Net/Util/AttributeSource.cs
index cda26f4..c4114c0 100644
--- a/src/Lucene.Net/Util/AttributeSource.cs
+++ b/src/Lucene.Net/Util/AttributeSource.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -111,7 +112,8 @@ namespace Lucene.Net.Util
// LUCENENET: If the weakreference is dead, we need to explicitly update its key.
// We synchronize on attClassImplMapLock to make the operation atomic.
- lock (attClassImplMapLock)
+ UninterruptableMonitor.Enter(attClassImplMapLock);
+ try
{
if (!attClassImplMap.TryGetValue(attClass, out var @ref) || !@ref.TryGetTarget(out clazz))
{
@@ -123,6 +125,10 @@ namespace Lucene.Net.Util
#endif
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(attClassImplMapLock);
+ }
return clazz;
}
diff --git a/src/Lucene.Net/Util/Fst/Util.cs b/src/Lucene.Net/Util/Fst/Util.cs
index 8e6c7b3..92bdf32 100644
--- a/src/Lucene.Net/Util/Fst/Util.cs
+++ b/src/Lucene.Net/Util/Fst/Util.cs
@@ -2,6 +2,7 @@
using J2N.Numerics;
using J2N.Text;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -441,10 +442,15 @@ namespace Lucene.Net.Util.Fst
// so we need to add some thread safety just in case.
// Perhaps it might make sense to wrap SortedSet into a type
// that provides thread safety.
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
queue.Remove(queue.Max);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
@@ -518,7 +524,8 @@ namespace Lucene.Net.Util.Fst
// so we need to add some thread safety just in case.
// Perhaps it might make sense to wrap SortedSet into a type
// that provides thread safety.
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
path = queue.Min;
if (path != null)
@@ -526,6 +533,10 @@ namespace Lucene.Net.Util.Fst
queue.Remove(path);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
if (path == null)
{
diff --git a/src/Lucene.Net/Util/InfoStream.cs b/src/Lucene.Net/Util/InfoStream.cs
index 7643ef5..243d66a 100644
--- a/src/Lucene.Net/Util/InfoStream.cs
+++ b/src/Lucene.Net/Util/InfoStream.cs
@@ -1,5 +1,6 @@
using System;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Util
{
@@ -68,20 +69,30 @@ namespace Lucene.Net.Util
{
get
{
- lock (typeof(InfoStream))
+ UninterruptableMonitor.Enter(typeof(InfoStream));
+ try
{
return defaultInfoStream;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(typeof(InfoStream));
+ }
}
set
{
- lock (typeof(InfoStream))
+ UninterruptableMonitor.Enter(typeof(InfoStream));
+ try
{
defaultInfoStream = value ?? throw new ArgumentNullException(
nameof(Default),
"Cannot set InfoStream default implementation to null. " +
"To disable logging use InfoStream.NO_OUTPUT");
}
+ finally
+ {
+ UninterruptableMonitor.Exit(typeof(InfoStream));
+ }
}
}
[lucenenet] 05/08: SWEEP: Lucene.Net.TestFramework: Changed all
lock statements to UninterruptableMonitor.Enter and
UninterruptableMonitor.Exit to prevent ThreadInterruptedException from
occurring when entering a lock.
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 152ffe658559f613afa3037467eea1165c261dee
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Thu Oct 14 20:42:02 2021 +0700
SWEEP: Lucene.Net.TestFramework: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
---
.../Analysis/BaseTokenStreamTestCase.cs | 1 +
.../Analysis/MockAnalyzer.cs | 8 +-
.../Codecs/RAMOnly/RAMOnlyPostingsFormat.cs | 17 +-
.../Index/BaseMergePolicyTestCase.cs | 8 +-
.../Index/BasePostingsFormatTestCase.cs | 7 +-
.../Search/RandomSimilarityProvider.cs | 15 +-
.../Search/SearchEquivalenceTestBase.cs | 7 +-
.../Store/MockDirectoryWrapper.cs | 211 ++++++++++++++++++---
.../Store/SlowClosingMockIndexInputWrapper.cs | 3 +-
.../Store/SlowOpeningMockIndexInputWrapper.cs | 3 +-
src/Lucene.Net.TestFramework/Util/LineFileDocs.cs | 36 +++-
.../Util/LuceneTestCase.cs | 28 ++-
src/Lucene.Net.TestFramework/Util/TestUtil.cs | 1 +
.../Util/ThrottledIndexOutput.cs | 1 +
14 files changed, 296 insertions(+), 50 deletions(-)
diff --git a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
index b26c20a..4e069df 100644
--- a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using RandomizedTesting.Generators;
using System;
diff --git a/src/Lucene.Net.TestFramework/Analysis/MockAnalyzer.cs b/src/Lucene.Net.TestFramework/Analysis/MockAnalyzer.cs
index a172ee0..cae547a 100644
--- a/src/Lucene.Net.TestFramework/Analysis/MockAnalyzer.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/MockAnalyzer.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Lucene.Net.Util.Automaton;
using System;
@@ -105,7 +106,8 @@ namespace Lucene.Net.Analysis
private TokenFilter MaybePayload(TokenFilter stream, string fieldName)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
previousMappings.TryGetValue(fieldName, out int? val);
if (val == null)
@@ -155,6 +157,10 @@ namespace Lucene.Net.Analysis
return new MockFixedLengthPayloadFilter(random, stream, (int)val);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public void SetPositionIncrementGap(int positionIncrementGap)
diff --git a/src/Lucene.Net.TestFramework/Codecs/RAMOnly/RAMOnlyPostingsFormat.cs b/src/Lucene.Net.TestFramework/Codecs/RAMOnly/RAMOnlyPostingsFormat.cs
index 990f566..c5dc4f5 100644
--- a/src/Lucene.Net.TestFramework/Codecs/RAMOnly/RAMOnlyPostingsFormat.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/RAMOnly/RAMOnlyPostingsFormat.cs
@@ -1,8 +1,9 @@
-using J2N.Text;
+using J2N.Text;
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -609,10 +610,15 @@ namespace Lucene.Net.Codecs.RAMOnly
RAMPostings postings = new RAMPostings();
RAMFieldsConsumer consumer = new RAMFieldsConsumer(postings);
- lock (state)
+ UninterruptableMonitor.Enter(state);
+ try
{
state[id] = postings;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(state);
+ }
return consumer;
}
@@ -641,10 +647,15 @@ namespace Lucene.Net.Codecs.RAMOnly
}
}
- lock (state)
+ UninterruptableMonitor.Enter(state);
+ try
{
return state[id];
}
+ finally
+ {
+ UninterruptableMonitor.Exit(state);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.TestFramework/Index/BaseMergePolicyTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseMergePolicyTestCase.cs
index ed3663f..9491259 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseMergePolicyTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseMergePolicyTestCase.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using RandomizedTesting.Generators;
using System;
@@ -91,7 +92,8 @@ namespace Lucene.Net.Index
public override void Merge(IndexWriter writer, MergeTrigger trigger, bool newMergesFound)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!mayMerge.Value && writer.NextMerge() != null)
{
@@ -99,6 +101,10 @@ namespace Lucene.Net.Index
}
base.Merge(writer, trigger, newMergesFound);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.TestFramework/Index/BasePostingsFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BasePostingsFormatTestCase.cs
index 7af790a..5927d6e 100644
--- a/src/Lucene.Net.TestFramework/Index/BasePostingsFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BasePostingsFormatTestCase.cs
@@ -371,13 +371,18 @@ namespace Lucene.Net.Index
// //[Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitialize(Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior.BeforeEachDerivedClass)]
// new public static void BeforeClass(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext context)
// {
-// lock (initalizationLock)
+// UninterruptableMonitor.Enter(initializationLock);
+// try
// {
// if (!initalizationLock.Contains(context.FullyQualifiedTestClassName))
// initalizationLock.Add(context.FullyQualifiedTestClassName);
// else
// return; // Only allow this class to initialize once (MSTest bug)
// }
+// finally
+// {
+// UninterruptableMonitor.Exit(initializationLock);
+// }
//#else
#if TESTFRAMEWORK_NUNIT
[NUnit.Framework.OneTimeSetUp]
diff --git a/src/Lucene.Net.TestFramework/Search/RandomSimilarityProvider.cs b/src/Lucene.Net.TestFramework/Search/RandomSimilarityProvider.cs
index 1d19759..2cf40a2 100644
--- a/src/Lucene.Net.TestFramework/Search/RandomSimilarityProvider.cs
+++ b/src/Lucene.Net.TestFramework/Search/RandomSimilarityProvider.cs
@@ -1,6 +1,7 @@
using J2N.Collections.Generic.Extensions;
using Lucene.Net.Diagnostics;
using Lucene.Net.Search.Similarities;
+using Lucene.Net.Support.Threading;
using RandomizedTesting.Generators;
using System;
using System.Collections.Generic;
@@ -70,7 +71,8 @@ namespace Lucene.Net.Search
public override Similarity Get(string field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (Debugging.AssertsEnabled) Debugging.Assert(field != null);
if (!previousMappings.TryGetValue(field, out Similarity sim) || sim == null)
@@ -80,6 +82,10 @@ namespace Lucene.Net.Search
}
return sim;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// all the similarities that we rotate through
@@ -139,7 +145,8 @@ namespace Lucene.Net.Search
public override string ToString()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// LUCENENET: Use StringBuilder for better efficiency
var sb = new StringBuilder();
@@ -157,6 +164,10 @@ namespace Lucene.Net.Search
sb.AppendFormat(J2N.Text.StringFormatter.InvariantCulture, "{0}", previousMappings);
return sb.ToString();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.TestFramework/Search/SearchEquivalenceTestBase.cs b/src/Lucene.Net.TestFramework/Search/SearchEquivalenceTestBase.cs
index f2fb843..c846fda 100644
--- a/src/Lucene.Net.TestFramework/Search/SearchEquivalenceTestBase.cs
+++ b/src/Lucene.Net.TestFramework/Search/SearchEquivalenceTestBase.cs
@@ -64,13 +64,18 @@ namespace Lucene.Net.Search
// //[Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitialize(Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior.BeforeEachDerivedClass)]
// new public static void BeforeClass(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext context)
// {
-// lock (initalizationLock)
+// UninterruptableMonitor.Enter(initializationLock);
+// try
// {
// if (!initalizationLock.Contains(context.FullyQualifiedTestClassName))
// initalizationLock.Add(context.FullyQualifiedTestClassName);
// else
// return; // Only allow this class to initialize once (MSTest bug)
// }
+// finally
+// {
+// UninterruptableMonitor.Exit(initializationLock);
+// }
//#else
#if TESTFRAMEWORK_NUNIT
[NUnit.Framework.OneTimeSetUp]
diff --git a/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs b/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
index dd4be0a..aef6c3b 100644
--- a/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/MockDirectoryWrapper.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using RandomizedTesting.Generators;
using System;
@@ -135,7 +136,8 @@ namespace Lucene.Net.Store
private void Init()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (openFiles == null)
{
@@ -152,6 +154,10 @@ namespace Lucene.Net.Store
unSyncedFiles = new JCG.HashSet<string>(StringComparer.Ordinal);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public MockDirectoryWrapper(Random random, Directory @delegate)
@@ -234,7 +240,8 @@ namespace Lucene.Net.Store
[MethodImpl(MethodImplOptions.NoInlining)]
public override void Sync(ICollection<string> names)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
MaybeThrowDeterministicException();
@@ -258,11 +265,16 @@ namespace Lucene.Net.Store
unSyncedFiles.ExceptWith(names);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public long GetSizeInBytes()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (m_input is RAMDirectory ramDirectory)
{
@@ -279,6 +291,10 @@ namespace Lucene.Net.Store
return size;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -287,7 +303,8 @@ namespace Lucene.Net.Store
/// </summary>
public virtual void Crash()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
crashed = true;
openFiles = new Dictionary<string, int>(StringComparer.Ordinal);
@@ -387,15 +404,24 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void ClearCrash()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
crashed = false;
openLocks.Clear();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual long MaxSizeInBytes
@@ -494,18 +520,24 @@ namespace Lucene.Net.Store
[MethodImpl(MethodImplOptions.NoInlining)]
public override void DeleteFile(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
DeleteFile(name, false);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// if there are any exceptions in OpenFileHandles
// capture those as inner exceptions
private Exception WithAdditionalErrorInformation(Exception t, string name, bool input)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
foreach (var ent in openFileHandles)
{
@@ -522,6 +554,10 @@ namespace Lucene.Net.Store
}
return t;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -541,7 +577,8 @@ namespace Lucene.Net.Store
[MethodImpl(MethodImplOptions.NoInlining)]
private void DeleteFile(string name, bool forced)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
@@ -578,14 +615,23 @@ namespace Lucene.Net.Store
}
m_input.DeleteFile(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual ICollection<string> GetOpenDeletedFiles()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return new JCG.HashSet<string>(openFilesDeleted, StringComparer.Ordinal);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool failOnCreateOutput = true;
@@ -598,7 +644,8 @@ namespace Lucene.Net.Store
public override IndexOutput CreateOutput(string name, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeThrowDeterministicException();
MaybeThrowIOExceptionOnOpen(name);
@@ -612,13 +659,18 @@ namespace Lucene.Net.Store
throw new IOException("cannot createOutput after crash");
}
Init();
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (preventDoubleWrite && createdFiles.Contains(name) && !name.Equals("segments.gen", StringComparison.Ordinal))
{
throw new IOException("file \"" + name + "\" was already written to");
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
if ((noDeleteOpenFile || assertNoDeleteOpenFile) && openFiles.ContainsKey(name))
{
if (!assertNoDeleteOpenFile)
@@ -683,6 +735,10 @@ namespace Lucene.Net.Store
return io;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal enum Handle
@@ -696,7 +752,8 @@ namespace Lucene.Net.Store
{
//Trace.TraceInformation("Add {0} {1}", c, name);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (openFiles.TryGetValue(name, out int v))
{
@@ -712,6 +769,10 @@ namespace Lucene.Net.Store
openFileHandles[c] = RuntimeException.Create("unclosed Index" + handle.ToString() + ": " + name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private bool failOnOpenInput = true;
@@ -724,7 +785,8 @@ namespace Lucene.Net.Store
public override IndexInput OpenInput(string name, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeThrowDeterministicException();
MaybeThrowIOExceptionOnOpen(name);
@@ -772,13 +834,18 @@ namespace Lucene.Net.Store
AddFileHandle(ii, name, Handle.Input);
return ii;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
/// Provided for testing purposes. Use <see cref="GetSizeInBytes()"/> instead. </summary>
public long GetRecomputedSizeInBytes()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!(m_input is RAMDirectory))
{
@@ -791,6 +858,10 @@ namespace Lucene.Net.Store
}
return size;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -802,7 +873,8 @@ namespace Lucene.Net.Store
public long GetRecomputedActualSizeInBytes()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!(m_input is RAMDirectory))
{
@@ -815,6 +887,10 @@ namespace Lucene.Net.Store
}
return size;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// NOTE: this is off by default; see LUCENE-5574
@@ -843,7 +919,8 @@ namespace Lucene.Net.Store
protected override void Dispose(bool disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (disposing)
{
@@ -1024,13 +1101,18 @@ namespace Lucene.Net.Store
throttledOutput.Dispose(); // LUCENENET specific
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void RemoveOpenFile(IDisposable c, string name)
{
//Trace.TraceInformation("Rem {0} {1}", c, name);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (openFiles.TryGetValue(name, out int v))
{
@@ -1049,23 +1131,37 @@ namespace Lucene.Net.Store
openFileHandles.TryRemove(c, out Exception _);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void RemoveIndexOutput(IndexOutput @out, string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
openFilesForWrite.Remove(name);
RemoveOpenFile(@out, name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void RemoveIndexInput(IndexInput @in, string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
RemoveOpenFile(@in, name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// LUCENENET specific - de-nested Failure
@@ -1078,7 +1174,8 @@ namespace Lucene.Net.Store
/// </summary>
public virtual void FailOn(Failure fail)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (failures == null)
{
@@ -1086,6 +1183,10 @@ namespace Lucene.Net.Store
}
failures.Add(fail);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -1094,7 +1195,8 @@ namespace Lucene.Net.Store
/// </summary>
internal virtual void MaybeThrowDeterministicException()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (failures != null)
{
@@ -1104,57 +1206,87 @@ namespace Lucene.Net.Store
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override string[] ListAll()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
return m_input.ListAll();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
[Obsolete("this method will be removed in 5.0")]
public override bool FileExists(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
return m_input.FileExists(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override long FileLength(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
return m_input.FileLength(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override Lock MakeLock(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
return LockFactory.MakeLock(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void ClearLock(string name)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
LockFactory.ClearLock(name);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void SetLockFactory(LockFactory lockFactory)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
// sneaky: we must pass the original this way to the dir, because
@@ -1163,13 +1295,18 @@ namespace Lucene.Net.Store
// now set our wrapped factory here
this.m_lockFactory = new MockLockFactoryWrapper(this, lockFactory);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override LockFactory LockFactory
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
if (wrapLockFactory)
@@ -1181,26 +1318,40 @@ namespace Lucene.Net.Store
return m_input.LockFactory;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
public override string GetLockID()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
return m_input.GetLockID();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void Copy(Directory to, string src, string dest, IOContext context)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
MaybeYield();
// randomize the IOContext here?
m_input.Copy(to, src, dest, context);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override IndexInputSlicer CreateSlicer(string name, IOContext context)
diff --git a/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs b/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
index c65685d..5af0dbe 100644
--- a/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support.Threading;
+using System;
using System.Threading;
namespace Lucene.Net.Store
diff --git a/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs b/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
index 684e118..113c76c 100644
--- a/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support.Threading;
+using System;
using System.Threading;
namespace Lucene.Net.Store
diff --git a/src/Lucene.Net.TestFramework/Util/LineFileDocs.cs b/src/Lucene.Net.TestFramework/Util/LineFileDocs.cs
index f81fe3e..79057d3 100644
--- a/src/Lucene.Net.TestFramework/Util/LineFileDocs.cs
+++ b/src/Lucene.Net.TestFramework/Util/LineFileDocs.cs
@@ -2,6 +2,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Documents;
using Lucene.Net.Support.IO;
+using Lucene.Net.Support.Threading;
using RandomizedTesting.Generators;
using System;
using System.Globalization;
@@ -70,7 +71,8 @@ namespace Lucene.Net.Util
private void Close()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (reader != null)
{
@@ -83,6 +85,10 @@ namespace Lucene.Net.Util
tempFilePath = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private static Task DeleteAsync(string path)
@@ -111,11 +117,16 @@ namespace Lucene.Net.Util
{
if (disposing)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
Close();
threadDocs?.Dispose();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
@@ -145,7 +156,8 @@ namespace Lucene.Net.Util
private void Open(Random random)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
Stream @is = null;
bool needSkip = true, isExternal = false;
@@ -232,16 +244,25 @@ namespace Lucene.Net.Util
reader.ReadLine();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public virtual void Reset(Random random)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
Close();
Open(random);
id.Value = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private const char SEP = '\t';
@@ -301,7 +322,8 @@ namespace Lucene.Net.Util
public virtual Document NextDoc()
{
string line;
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
line = reader.ReadLine();
if (line == null)
@@ -316,6 +338,10 @@ namespace Lucene.Net.Util
line = reader.ReadLine();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
DocState docState = threadDocs.Value;
if (docState == null)
diff --git a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
index fb9a072..f803a3a 100644
--- a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
@@ -183,7 +183,8 @@ namespace Lucene.Net.Util
public LuceneTestCase()
{
- lock (initalizationLock)
+ UninterruptableMonitor.Enter(initializationLock);
+ try
{
var thisType = this.GetType();
if (!initalizationLock.Contains(thisType.FullName))
@@ -201,6 +202,10 @@ namespace Lucene.Net.Util
BeforeClass();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(initializationLock);
+ }
}
#else
{
@@ -1050,7 +1055,8 @@ namespace Lucene.Net.Util
if (context == null)
throw new ArgumentNullException(nameof(context));
- lock (initalizationLock)
+ UninterruptableMonitor.Enter(initializationLock);
+ try
{
if (!initalizationLock.Contains(context.FullyQualifiedTestClassName))
initalizationLock.Add(context.FullyQualifiedTestClassName);
@@ -1067,6 +1073,10 @@ namespace Lucene.Net.Util
_testClassType = Type.GetType(_testClassName);
#endif
}
+ finally
+ {
+ UninterruptableMonitor.Exit(initializationLock);
+ }
try
{
@@ -3495,10 +3505,15 @@ namespace Lucene.Net.Util
Console.Error.WriteLine("INFO: Will leave temporary file: " + f.FullName);
return;
}
- lock (cleanupQueueLock)
+ UninterruptableMonitor.Enter(cleanupQueueLock);
+ try
{
cleanupQueue.Push(f);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(cleanupQueueLock);
+ }
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -3513,7 +3528,8 @@ namespace Lucene.Net.Util
FileSystemInfo[] everything;
string tempDirBasePath;
- lock (cleanupQueueLock)
+ UninterruptableMonitor.Enter(cleanupQueueLock);
+ try
{
tempDirBasePath = tempDirBase?.FullName;
tempDirBase = null;
@@ -3522,6 +3538,10 @@ namespace Lucene.Net.Util
everything = cleanupQueue.ToArray();
cleanupQueue.Clear();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(cleanupQueueLock);
+ }
// LUCENENET specific - If the everything array is empty, there is no reason
// to continue.
diff --git a/src/Lucene.Net.TestFramework/Util/TestUtil.cs b/src/Lucene.Net.TestFramework/Util/TestUtil.cs
index 2d880b9..9a774b6 100644
--- a/src/Lucene.Net.TestFramework/Util/TestUtil.cs
+++ b/src/Lucene.Net.TestFramework/Util/TestUtil.cs
@@ -864,6 +864,7 @@ namespace Lucene.Net.Util
// {
// try
// {
+ // UninterruptableMonitor.RestoreInterrupt();
// ex.shutdown();
// ex.awaitTermination(1, TimeUnit.SECONDS);
// }
diff --git a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
index 4892032..cf205f3 100644
--- a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
+++ b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Store;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Threading;
[lucenenet] 08/08: Lucene.Net.Tests.Index.TestIndexWriter: Removed
[AwaitsFix] attribute from TestThreadInterruptDeadlock() and
TestTwoThreadsInterruptDeadlock(), since they now are passing
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 3dcffb2929662ffb9c4678458eaf90f0df300f92
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Oct 17 14:17:47 2021 +0700
Lucene.Net.Tests.Index.TestIndexWriter: Removed [AwaitsFix] attribute from TestThreadInterruptDeadlock() and TestTwoThreadsInterruptDeadlock(), since they now are passing
---
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
index bc1b84e..ed87d16 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
@@ -1476,7 +1476,6 @@ namespace Lucene.Net.Index
[Test]
[Slow]
- [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails on .NET Core
public virtual void TestThreadInterruptDeadlock()
{
IndexerThreadInterrupt t = new IndexerThreadInterrupt(this);
@@ -1517,7 +1516,6 @@ namespace Lucene.Net.Index
/// testThreadInterruptDeadlock but with 2 indexer threads </summary>
[Test]
[Slow]
- [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test occasionally fails on .NET Core
public virtual void TestTwoThreadsInterruptDeadlock()
{
IndexerThreadInterrupt t1 = new IndexerThreadInterrupt(this);
[lucenenet] 06/08: SWEEP: Changed all lock statements to
UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent
ThreadInterruptedException from occurring when entering a lock.
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 7c357e78adf22207279bc998863b63d714d3442d
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Thu Oct 14 16:00:18 2021 +0700
SWEEP: Changed all lock statements to UninterruptableMonitor.Enter and UninterruptableMonitor.Exit to prevent ThreadInterruptedException from occurring when entering a lock.
---
.../Analysis/Th/ThaiTokenizer.cs | 71 ++++++++++++++---
.../Analysis/Util/AnalysisSPILoader.cs | 8 +-
.../Analysis/Util/BufferedCharFilter.cs | 43 ++++++++--
.../Analysis/Icu/Segmentation/ICUTokenizer.cs | 26 +++++-
.../Tools/NLPChunkerOp.cs | 8 +-
.../Tools/NLPNERTaggerOp.cs | 8 +-
.../Tools/NLPPOSTaggerOp.cs | 8 +-
.../Tools/NLPSentenceDetectorOp.cs | 8 +-
.../Tools/NLPTokenizerOp.cs | 8 +-
.../Hhmm/BigramDictionary.cs | 8 +-
.../Hhmm/WordDictionary.cs | 8 +-
src/Lucene.Net.Benchmark/ByTask/Benchmark.cs | 8 +-
.../ByTask/Feeds/AbstractQueryMaker.cs | 8 +-
.../ByTask/Feeds/ContentItemsSource.cs | 15 +++-
.../ByTask/Feeds/DirContentSource.cs | 15 +++-
.../ByTask/Feeds/EnwikiContentSource.cs | 63 +++++++++++----
.../ByTask/Feeds/LineDocSource.cs | 8 +-
.../ByTask/Feeds/LongToEnglishContentSource.cs | 17 +++-
.../ByTask/Feeds/LongToEnglishQueryMaker.cs | 15 +++-
.../ByTask/Feeds/ReutersContentSource.cs | 15 +++-
.../ByTask/Feeds/SingleDocSource.cs | 18 ++++-
.../ByTask/Feeds/TrecContentSource.cs | 15 +++-
src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs | 57 ++++++++++++--
src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs | 22 +++++-
.../ByTask/Tasks/NearRealtimeReaderTask.cs | 1 +
.../ByTask/Tasks/TaskSequence.cs | 1 +
src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs | 3 +-
.../ByTask/Tasks/WriteLineDocTask.cs | 15 +++-
.../Memory/DirectDocValuesProducer.cs | 36 +++++++--
.../Memory/MemoryDocValuesProducer.cs | 36 +++++++--
.../SimpleText/SimpleTextFieldsReader.cs | 8 +-
src/Lucene.Net.Facet/FacetsConfig.cs | 36 +++++++--
.../Taxonomy/CachedOrdinalsReader.cs | 15 +++-
.../Taxonomy/Directory/DirectoryTaxonomyWriter.cs | 92 +++++++++++++++++++---
src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs | 8 +-
.../WriterCache/Cl2oTaxonomyWriterCache.cs | 8 +-
.../Taxonomy/WriterCache/LruTaxonomyWriterCache.cs | 36 +++++++--
.../Taxonomy/WriterCache/NameIntCacheLRU.cs | 8 +-
.../AbstractFirstPassGroupingCollector.cs | 15 +++-
src/Lucene.Net.Misc/Document/LazyDocument.cs | 15 +++-
.../Surround/Query/BasicQueryFactory.cs | 8 +-
.../Xml/Builders/CachedFilterBuilder.cs | 8 +-
.../Xml/Builders/UserInputQueryBuilder.cs | 8 +-
src/Lucene.Net.Replicator/LocalReplicator.cs | 50 ++++++++++--
src/Lucene.Net.Replicator/ReplicationClient.cs | 14 +++-
src/Lucene.Net.Suggest/Spell/SpellChecker.cs | 45 +++++++++--
.../Suggest/Analyzing/AnalyzingInfixSuggester.cs | 8 +-
.../Suggest/Fst/FSTCompletionLookup.cs | 15 +++-
src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs | 15 +++-
.../Index/BaseDocValuesFormatTestCase.cs | 1 +
.../Index/ThreadedIndexingAndSearchingTestCase.cs | 1 +
.../Analysis/Th/TestThaiAnalyzer.cs | 1 +
.../Analysis/Icu/Segmentation/TestICUTokenizer.cs | 1 +
.../ByTask/Tasks/CountingSearchTestTask.cs | 8 +-
src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs | 17 ++--
.../Taxonomy/TestSearcherTaxonomyManager.cs | 1 +
.../Taxonomy/TestTaxonomyCombined.cs | 2 +
.../IndexAndTaxonomyReplicationClientTest.cs | 1 +
.../IndexReplicationClientTest.cs | 1 +
.../LocalReplicatorTest.cs | 1 +
.../Spell/TestSpellChecker.cs | 1 +
.../Analyzing/AnalyzingInfixSuggesterTest.cs | 1 +
src/Lucene.Net.Tests/Index/TestAddIndexes.cs | 22 +++++-
src/Lucene.Net.Tests/Index/TestBagOfPositions.cs | 1 +
src/Lucene.Net.Tests/Index/TestBagOfPostings.cs | 1 +
.../Index/TestConcurrentMergeScheduler.cs | 1 +
src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs | 1 +
src/Lucene.Net.Tests/Index/TestDirectoryReader.cs | 1 +
.../Index/TestDirectoryReaderReopen.cs | 35 ++++++--
.../Index/TestDocumentsWriterStallControl.cs | 4 +-
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 33 +++++++-
.../Index/TestIndexWriterExceptions.cs | 8 +-
.../Index/TestIndexWriterMerging.cs | 8 +-
.../Index/TestIndexWriterNRTIsCurrent.cs | 1 +
.../Index/TestIndexWriterOnJRECrash.cs | 1 +
.../Index/TestIndexWriterReader.cs | 8 +-
.../Index/TestNRTReaderWithThreads.cs | 1 +
src/Lucene.Net.Tests/Index/TestNeverDelete.cs | 1 +
src/Lucene.Net.Tests/Index/TestPayloads.cs | 22 +++++-
.../Index/TestSnapshotDeletionPolicy.cs | 1 +
src/Lucene.Net.Tests/Index/TestStressIndexing2.cs | 22 +++++-
src/Lucene.Net.Tests/Index/TestStressNRT.cs | 29 ++++++-
src/Lucene.Net.Tests/Index/TestTransactions.cs | 15 +++-
.../Search/TestControlledRealTimeReopenThread.cs | 8 +-
.../Search/TestMultiThreadTermVectors.cs | 1 +
src/Lucene.Net.Tests/Search/TestSearcherManager.cs | 15 +++-
.../Search/TestTimeLimitingCollector.cs | 8 +-
src/Lucene.Net.Tests/Store/TestLockFactory.cs | 1 +
src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs | 1 +
src/Lucene.Net.Tests/Util/TestSetOnce.cs | 1 +
90 files changed, 1087 insertions(+), 185 deletions(-)
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Th/ThaiTokenizer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Th/ThaiTokenizer.cs
index e3e7323..3bc1a83 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Th/ThaiTokenizer.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Th/ThaiTokenizer.cs
@@ -1,9 +1,10 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
#if FEATURE_BREAKITERATOR
using ICU4N.Text;
using J2N;
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Analysis.Util;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -54,14 +55,28 @@ namespace Lucene.Net.Analysis.Th
private static BreakIterator LoadProto()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
return BreakIterator.GetWordInstance(new CultureInfo("th"));
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private static BreakIterator LoadSentenceProto()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
return BreakIterator.GetSentenceInstance(CultureInfo.InvariantCulture);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private readonly ThaiWordBreaker wordBreaker;
@@ -87,45 +102,79 @@ namespace Lucene.Net.Analysis.Th
{
// LUCENENET specific - DBBI_AVAILABLE removed because ICU always has a dictionary-based BreakIterator
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
wordBreaker = new ThaiWordBreaker((BreakIterator)proto.Clone());
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
termAtt = AddAttribute<ICharTermAttribute>();
offsetAtt = AddAttribute<IOffsetAttribute>();
}
private static BreakIterator CreateSentenceClone()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
return (BreakIterator)sentenceProto.Clone();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public override void Reset()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
base.Reset();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public override State CaptureState()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
return base.CaptureState();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
protected override void SetNextSentence(int sentenceStart, int sentenceEnd)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
this.sentenceStart = sentenceStart;
this.sentenceEnd = sentenceEnd;
wrapper.SetText(m_buffer, sentenceStart, sentenceEnd - sentenceStart);
wordBreaker.SetText(new string(wrapper.Text, wrapper.Start, wrapper.Length));
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
protected override bool IncrementWord()
{
int start, end;
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
start = wordBreaker.Current;
if (start == BreakIterator.Done)
@@ -151,6 +200,10 @@ namespace Lucene.Net.Analysis.Th
offsetAtt.SetOffset(CorrectOffset(m_offset + sentenceStart + start), CorrectOffset(m_offset + sentenceStart + end));
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/AnalysisSPILoader.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/AnalysisSPILoader.cs
index 3d4224b..5c27659 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/AnalysisSPILoader.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/AnalysisSPILoader.cs
@@ -1,6 +1,7 @@
// Lucene version compatibility level 4.8.1
using J2N.Collections.Generic.Extensions;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -60,7 +61,8 @@ namespace Lucene.Net.Analysis.Util
/// </summary>
public void Reload()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
IDictionary<string, Type> services = new JCG.LinkedDictionary<string, Type>(this.services);
SPIClassIterator<S> loader = SPIClassIterator<S>.Get();
@@ -98,6 +100,10 @@ namespace Lucene.Net.Analysis.Util
}
this.services = services.AsReadOnly();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public S NewInstance(string name, IDictionary<string, string> args)
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs
index 4d6a86e..bceb42c 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/BufferedCharFilter.cs
@@ -3,6 +3,7 @@
// https://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/
using Lucene.Net.Analysis.CharFilters;
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
using System.Text;
@@ -119,7 +120,8 @@ namespace Lucene.Net.Analysis.Util
#if FEATURE_TEXTWRITER_CLOSE
this.isDisposing = true;
#endif
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
if (!IsClosed)
{
@@ -128,6 +130,10 @@ namespace Lucene.Net.Analysis.Util
buf = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
#if FEATURE_TEXTWRITER_CLOSE
this.isDisposing = false;
#endif
@@ -225,12 +231,17 @@ namespace Lucene.Net.Analysis.Util
{
throw new ArgumentOutOfRangeException(nameof(markLimit), "Read-ahead limit < 0");
}
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
EnsureOpen();
this.markLimit = markLimit;
mark = pos;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
}
/// <summary>
@@ -253,7 +264,8 @@ namespace Lucene.Net.Analysis.Util
/// <exception cref="IOException">If this reader is disposed or some other I/O error occurs.</exception>
public override int Read()
{
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
EnsureOpen();
/* Are there buffered characters available? */
@@ -263,6 +275,10 @@ namespace Lucene.Net.Analysis.Util
}
return -1;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
}
/// <summary>
@@ -483,13 +499,18 @@ namespace Lucene.Net.Analysis.Util
{
get
{
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
EnsureOpen();
// LUCENENET specific: only CharFilter derived types support IsReady
var charFilter = @in as CharFilter;
return ((end - pos) > 0) || (charFilter != null && charFilter.IsReady);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
}
}
@@ -503,7 +524,8 @@ namespace Lucene.Net.Analysis.Util
/// <seealso cref="IsMarkSupported"/>
public override void Reset()
{
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
EnsureOpen();
if (mark < 0)
@@ -513,6 +535,10 @@ namespace Lucene.Net.Analysis.Util
}
pos = mark;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
}
/// <summary>
@@ -534,7 +560,8 @@ namespace Lucene.Net.Analysis.Util
{
throw new ArgumentOutOfRangeException(nameof(amount), "skip value is negative");
}
- lock (m_lock)
+ UninterruptableMonitor.Enter(m_lock);
+ try
{
EnsureOpen();
if (amount < 1)
@@ -566,6 +593,10 @@ namespace Lucene.Net.Analysis.Util
}
return amount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_lock);
+ }
}
#region LUCENENET Specific Methods
diff --git a/src/Lucene.Net.Analysis.ICU/Analysis/Icu/Segmentation/ICUTokenizer.cs b/src/Lucene.Net.Analysis.ICU/Analysis/Icu/Segmentation/ICUTokenizer.cs
index e9d207a..ab79760 100644
--- a/src/Lucene.Net.Analysis.ICU/Analysis/Icu/Segmentation/ICUTokenizer.cs
+++ b/src/Lucene.Net.Analysis.ICU/Analysis/Icu/Segmentation/ICUTokenizer.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Analysis.Icu.TokenAttributes;
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Diagnostics;
using System.IO;
@@ -111,7 +112,8 @@ namespace Lucene.Net.Analysis.Icu.Segmentation
public override bool IncrementToken()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
ClearAttributes();
if (length == 0)
@@ -124,14 +126,25 @@ namespace Lucene.Net.Analysis.Icu.Segmentation
}
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public override void Reset()
{
base.Reset();
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
breaker.SetText(buffer, 0, 0);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
length = usableLength = offset = 0;
}
@@ -193,8 +206,15 @@ namespace Lucene.Net.Analysis.Icu.Segmentation
*/
}
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
+ {
breaker.SetText(buffer, 0, Math.Max(0, usableLength));
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
// TODO: refactor to a shared readFully somewhere
diff --git a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPChunkerOp.cs b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPChunkerOp.cs
index de53e3b..8f870b7 100644
--- a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPChunkerOp.cs
+++ b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPChunkerOp.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 8.2.0
+using Lucene.Net.Support.Threading;
using opennlp.tools.chunker;
@@ -36,13 +37,18 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
public virtual string[] GetChunks(string[] words, string[] tags, double[] probs)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
string[] chunks = chunker.chunk(words, tags);
if (probs != null)
chunker.probs(probs);
return chunks;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPNERTaggerOp.cs b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPNERTaggerOp.cs
index 614ae52..733bcd0 100644
--- a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPNERTaggerOp.cs
+++ b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPNERTaggerOp.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 8.2.0
+using Lucene.Net.Support.Threading;
using opennlp.tools.namefind;
using opennlp.tools.util;
@@ -53,10 +54,15 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
public virtual void Reset()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
nameFinder.clearAdaptiveData();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPPOSTaggerOp.cs b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPPOSTaggerOp.cs
index 2f1e090..cce97eb 100644
--- a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPPOSTaggerOp.cs
+++ b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPPOSTaggerOp.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 8.2.0
+using Lucene.Net.Support.Threading;
using opennlp.tools.postag;
namespace Lucene.Net.Analysis.OpenNlp.Tools
@@ -35,10 +36,15 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
public virtual string[] GetPOSTags(string[] words)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return tagger.tag(words);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPSentenceDetectorOp.cs b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPSentenceDetectorOp.cs
index 70c69ac..41ddb17 100644
--- a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPSentenceDetectorOp.cs
+++ b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPSentenceDetectorOp.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 8.2.0
+using Lucene.Net.Support.Threading;
using opennlp.tools.sentdetect;
using opennlp.tools.util;
@@ -41,7 +42,8 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
public virtual Span[] SplitSentences(string line)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (sentenceSplitter != null)
{
@@ -54,6 +56,10 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
return shorty;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPTokenizerOp.cs b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPTokenizerOp.cs
index 81df103..98ca819 100644
--- a/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPTokenizerOp.cs
+++ b/src/Lucene.Net.Analysis.OpenNLP/Tools/NLPTokenizerOp.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 8.2.0
+using Lucene.Net.Support.Threading;
using opennlp.tools.tokenize;
using opennlp.tools.util;
@@ -41,7 +42,8 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
public virtual Span[] GetTerms(string sentence)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (tokenizer == null)
{
@@ -51,6 +53,10 @@ namespace Lucene.Net.Analysis.OpenNlp.Tools
}
return tokenizer.tokenizePos(sentence);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Analysis.SmartCn/Hhmm/BigramDictionary.cs b/src/Lucene.Net.Analysis.SmartCn/Hhmm/BigramDictionary.cs
index 2925dd6..c220ad3 100644
--- a/src/Lucene.Net.Analysis.SmartCn/Hhmm/BigramDictionary.cs
+++ b/src/Lucene.Net.Analysis.SmartCn/Hhmm/BigramDictionary.cs
@@ -1,6 +1,7 @@
// lucene version compatibility level: 4.8.1
using J2N;
using J2N.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
using System.Text;
@@ -58,7 +59,8 @@ namespace Lucene.Net.Analysis.Cn.Smart.Hhmm
public static BigramDictionary GetInstance()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (singleInstance == null)
{
@@ -81,6 +83,10 @@ namespace Lucene.Net.Analysis.Cn.Smart.Hhmm
}
return singleInstance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private bool LoadFromObj(FileInfo serialObj)
diff --git a/src/Lucene.Net.Analysis.SmartCn/Hhmm/WordDictionary.cs b/src/Lucene.Net.Analysis.SmartCn/Hhmm/WordDictionary.cs
index 906e6b3..eee9188 100644
--- a/src/Lucene.Net.Analysis.SmartCn/Hhmm/WordDictionary.cs
+++ b/src/Lucene.Net.Analysis.SmartCn/Hhmm/WordDictionary.cs
@@ -1,6 +1,7 @@
// lucene version compatibility level: 4.8.1
using J2N;
using J2N.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.IO;
using System.Text;
@@ -76,7 +77,8 @@ namespace Lucene.Net.Analysis.Cn.Smart.Hhmm
/// <returns>singleton</returns>
public static WordDictionary GetInstance()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (singleInstance == null)
{
@@ -99,6 +101,10 @@ namespace Lucene.Net.Analysis.Cn.Smart.Hhmm
}
return singleInstance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Benchmark.cs b/src/Lucene.Net.Benchmark/ByTask/Benchmark.cs
index dc3f504..6b0b7a9 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Benchmark.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Benchmark.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.IO;
@@ -78,7 +79,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual void Execute()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (executed)
{
@@ -88,6 +90,10 @@ namespace Lucene.Net.Benchmarks.ByTask
runData.SetStartTimeMillis();
algorithm.Execute();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/AbstractQueryMaker.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/AbstractQueryMaker.cs
index fb6a2bf..a9d5f50 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/AbstractQueryMaker.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/AbstractQueryMaker.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Search;
+using Lucene.Net.Support.Threading;
using System;
using System.Text;
@@ -68,12 +69,17 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// return next qnum
protected virtual int NextQnum()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int res = m_qnum;
m_qnum = (m_qnum + 1) % m_queries.Length;
return res;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <seealso cref="IQueryMaker.MakeQuery(int)"/>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/ContentItemsSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/ContentItemsSource.cs
index be45d38..2029837 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/ContentItemsSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/ContentItemsSource.cs
@@ -1,5 +1,6 @@
using J2N.Text;
using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -71,21 +72,31 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
/// <summary>update count of bytes generated by this source</summary>
protected void AddBytes(long numBytes)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
bytesCount += numBytes;
totalBytesCount += numBytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>update count of items generated by this source</summary>
protected void AddItem()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
++itemCount;
++totalItemCount;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/DirContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/DirContentSource.cs
index 10e0248..b364796 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/DirContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/DirContentSource.cs
@@ -1,6 +1,7 @@
using J2N.Text;
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Support.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -182,7 +183,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
FileInfo f = null;
string name = null;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!inputFiles.MoveNext())
{
@@ -198,6 +200,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// System.err.println(f);
name = f.GetCanonicalPath() + "_" + iteration;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
string line = null;
string dateStr;
@@ -230,12 +236,17 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
public override void ResetInputs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
base.ResetInputs();
inputFiles = new Enumerator(dataDir);
iteration = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void SetConfig(Config config)
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
index 1e06701..633bf46 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
@@ -2,6 +2,7 @@
using J2N.Threading;
using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Sax;
using Sax.Helpers;
@@ -73,13 +74,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
t.Start();
}
string[] result;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (tuple == null && nmde == null && !threadDone && !stopped)
{
try
{
- Monitor.Wait(this);
+ UninterruptableMonitor.Wait(this);
}
catch (Exception ie) when (ie.IsInterruptedException())
{
@@ -106,6 +108,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// benchmark to stop the current alg:
throw new NoMoreDataException();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal string Time(string original)
@@ -144,13 +150,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
tmpTuple[DATE] = time.Replace('\t', ' ');
tmpTuple[BODY] = Regex.Replace(body, "[\t\n]", " ");
tmpTuple[ID] = id;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (tuple != null && !stopped)
{
try
{
- Monitor.Wait(this); //wait();
+ UninterruptableMonitor.Wait(this); //wait();
}
catch (System.Threading.ThreadInterruptedException ie)
{
@@ -158,7 +165,11 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
}
}
tuple = tmpTuple;
- Monitor.Pulse(this); //notify();
+ UninterruptableMonitor.Pulse(this); //notify();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
break;
@@ -211,7 +222,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
}
catch (Exception ioe) when (ioe.IsIOException())
{
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
if (localFileIS != outerInstance.@is)
{
@@ -221,14 +233,19 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// Exception is real
throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
}
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (stopped || !outerInstance.m_forever)
{
nmde = new NoMoreDataException();
- Monitor.Pulse(this); //notify();
+ UninterruptableMonitor.Pulse(this); //notify();
return;
}
else if (localFileIS == outerInstance.@is)
@@ -237,6 +254,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
outerInstance.@is = outerInstance.OpenInputStream();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
catch (SAXException sae)
@@ -249,10 +270,15 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
}
finally
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
threadDone = true;
- Monitor.Pulse(this); //Notify();
+ UninterruptableMonitor.Pulse(this); //Notify();
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
}
@@ -284,15 +310,20 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
internal void Stop()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
stopped = true;
if (tuple != null)
{
tuple = null;
- Monitor.Pulse(this); //Notify();
+ UninterruptableMonitor.Pulse(this); //Notify();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
@@ -342,16 +373,20 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
if (disposing)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
parser.Stop();
if (@is != null)
{
- Thread.Sleep(1); // LUCENENET: Allow parser to stop before Dispose() is called
@is.Dispose();
@is = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/LineDocSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/LineDocSource.cs
index 17a821e..505fc85 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/LineDocSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/LineDocSource.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Benchmarks.ByTask.Tasks;
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.IO;
@@ -85,7 +86,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
int myID;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
line = reader.ReadLine();
if (line == null)
@@ -109,6 +111,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// increment IDS only once...
myID = readCount++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
// The date String was written in the format of DateTools.dateToString.
docData.Clear();
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishContentSource.cs
index 7b4ab5f..7c05a68 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishContentSource.cs
@@ -1,4 +1,5 @@
-using Lucene.Net.Util;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Globalization;
@@ -38,12 +39,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// RuleBasedNumberFormat.SPELLOUT);
public override DocData GetNextDocData(DocData docData)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
docData.Clear();
// store the current counter to avoid synchronization later on
long curCounter;
- lock (this)
+ UninterruptableMonitor.Enter(this); // LUCENENET TODO: Since the whole method is synchronized, do we need this?
+ try
{
curCounter = counter;
if (counter == long.MaxValue)
@@ -55,6 +58,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
++counter;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
docData.Body = curCounter.ToWords(); //rnbf.format(curCounter);
docData.Name = "doc_" + curCounter.ToString(CultureInfo.InvariantCulture);
@@ -62,6 +69,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
docData.SetDate(new DateTime());
return docData;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override void ResetInputs()
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishQueryMaker.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishQueryMaker.cs
index 78580db..37ea280 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishQueryMaker.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/LongToEnglishQueryMaker.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
@@ -47,16 +48,22 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
public virtual Query MakeQuery()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
//return parser.Parse("" + rnbf.format(GetNextCounter()) + "");
return m_parser.Parse(GetNextCounter().ToWords());
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private long GetNextCounter()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (counter == long.MaxValue)
{
@@ -64,6 +71,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
}
return counter++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual void SetConfig(Config config)
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/ReutersContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/ReutersContentSource.cs
index 51815d9..13a78bb 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/ReutersContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/ReutersContentSource.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Support.IO;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -82,7 +83,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
FileInfo f = null;
string name = null;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (nextFile >= inputFiles.Count)
{
@@ -97,6 +99,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
f = inputFiles[nextFile++];
name = f.GetCanonicalPath() + "_" + iteration;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
using TextReader reader = new StreamReader(new FileStream(f.FullName, FileMode.Open, FileAccess.Read), Encoding.UTF8);
// First line is the date, 3rd is the title, rest is body
@@ -127,12 +133,17 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
public override void ResetInputs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
base.ResetInputs();
nextFile = 0;
iteration = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/SingleDocSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/SingleDocSource.cs
index 6fed314..6636af6 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/SingleDocSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/SingleDocSource.cs
@@ -1,4 +1,6 @@
-namespace Lucene.Net.Benchmarks.ByTask.Feeds
+using Lucene.Net.Support.Threading;
+
+namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -43,7 +45,8 @@
// return a new docid
private int NewDocID()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (docID > 0 && !m_forever)
{
@@ -51,6 +54,10 @@
}
return docID++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing) { }
@@ -67,11 +74,16 @@
public override void ResetInputs()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
base.ResetInputs();
docID = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/TrecContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/TrecContentSource.cs
index ec50045..a12d658 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/TrecContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/TrecContentSource.cs
@@ -1,5 +1,6 @@
using J2N.Text;
using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -261,7 +262,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
// protect reading from the TREC files by multiple threads. The rest of the
// method, i.e., parsing the content and returning the DocData can run unprotected.
- lock (@lock)
+ UninterruptableMonitor.Enter(@lock);
+ try
{
if (reader == null)
{
@@ -291,6 +293,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
docBuf.Length = 0;
Read(docBuf, TERMINATING_DOC, false, true);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(@lock);
+ }
// count char length of text to be parsed (may be larger than the resulted plain doc body text).
AddBytes(docBuf.Length);
@@ -305,13 +311,18 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
public override void ResetInputs()
{
- lock (@lock)
+ UninterruptableMonitor.Enter(@lock);
+ try
{
base.ResetInputs();
DoClose();
nextFile = 0;
iteration = 0;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(@lock);
+ }
}
public override void SetConfig(Config config)
diff --git a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
index 670e72b..2b6c50a 100644
--- a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Facet.Taxonomy;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -209,11 +210,16 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual object GetPerfObject(string key)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
perfObjects.TryGetValue(key, out object result);
return result;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -223,10 +229,15 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual void SetPerfObject(string key, object obj)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
perfObjects[key] = obj;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual long SetStartTimeMillis()
@@ -268,7 +279,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// <param name="taxoReader">The taxonomy reader to set.</param>
public virtual void SetTaxonomyReader(TaxonomyReader taxoReader)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (taxoReader == this.taxonomyReader)
{
@@ -285,6 +297,10 @@ namespace Lucene.Net.Benchmarks.ByTask
}
this.taxonomyReader = taxoReader;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -294,7 +310,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual TaxonomyReader GetTaxonomyReader()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (taxonomyReader != null)
{
@@ -302,6 +319,10 @@ namespace Lucene.Net.Benchmarks.ByTask
}
return taxonomyReader;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -320,7 +341,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual DirectoryReader GetIndexReader()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (indexReader != null)
{
@@ -328,6 +350,10 @@ namespace Lucene.Net.Benchmarks.ByTask
}
return indexReader;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -338,7 +364,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// <returns></returns>
public virtual IndexSearcher GetIndexSearcher()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (indexReader != null)
{
@@ -346,6 +373,10 @@ namespace Lucene.Net.Benchmarks.ByTask
}
return indexSearcher;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -357,7 +388,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// <param name="indexReader">The indexReader to set.</param>
public virtual void SetIndexReader(DirectoryReader indexReader)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (indexReader == this.indexReader)
{
@@ -382,6 +414,10 @@ namespace Lucene.Net.Benchmarks.ByTask
indexSearcher = null;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -441,7 +477,8 @@ namespace Lucene.Net.Benchmarks.ByTask
/// </summary>
public virtual IQueryMaker GetQueryMaker(ReadTask readTask)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// mapping the query maker by task class allows extending/adding new search/read tasks
// without needing to modify this class.
@@ -462,6 +499,10 @@ namespace Lucene.Net.Benchmarks.ByTask
}
return qm;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual IDictionary<string, AnalyzerFactory> AnalyzerFactories => analyzerFactories;
diff --git a/src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs b/src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs
index b12985f..ec76aa7 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Benchmarks.ByTask.Tasks;
using Lucene.Net.Benchmarks.ByTask.Utils;
+using Lucene.Net.Support.Threading;
using System.Collections.Generic;
namespace Lucene.Net.Benchmarks.ByTask.Stats
@@ -59,13 +60,18 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
/// <returns></returns>
public virtual TaskStats MarkTaskStart(PerfTask task, int round)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
TaskStats stats = new TaskStats(task, NextTaskRunNum(), round);
this.currentStats = stats;
points.Add(stats);
return stats;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public virtual TaskStats CurrentStats => currentStats;
@@ -73,10 +79,15 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
// return next task num
private int NextTaskRunNum()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return nextTaskRunNum++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
@@ -84,13 +95,18 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
/// </summary>
public virtual void MarkTaskEnd(TaskStats stats, int count)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int numParallelTasks = nextTaskRunNum - 1 - stats.TaskRunNum;
// note: if the stats were cleared, might be that this stats object is
// no longer in points, but this is just ok.
stats.MarkEnd(numParallelTasks, count);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
index fc0c264..4df03e7 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Globalization;
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
index f911a29..43bd6f9 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
@@ -1,6 +1,7 @@
using J2N.Threading;
using Lucene.Net.Benchmarks.ByTask.Feeds;
using Lucene.Net.Benchmarks.ByTask.Stats;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs
index 90600d0..a00a383 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/WaitTask.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support.Threading;
+using System;
using System.Globalization;
using System.Threading;
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
index b4f4209..53cfa89 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
@@ -3,6 +3,7 @@ using Lucene.Net.Benchmarks.ByTask.Feeds;
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Documents;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -160,10 +161,15 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
{
sb.Append(SEP).Append(f);
}
- lock (lineFileLock) // LUCENENET specific - lock to ensure writes don't collide for this instance
+ UninterruptableMonitor.Enter(lineFileLock);
+ try // LUCENENET specific - lock to ensure writes don't collide for this instance
{
@out.WriteLine(sb.ToString());
}
+ finally
+ {
+ UninterruptableMonitor.Exit(lineFileLock);
+ }
}
protected override string GetLogMessage(int recsCount)
@@ -202,10 +208,15 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
{
sb.Length--; // remove redundant last separator
// lineFileOut is a PrintWriter, which synchronizes internally in println.
- lock (lineFileLock) // LUCENENET specific - lock to ensure writes don't collide for this instance
+ UninterruptableMonitor.Enter(lineFileLock); // LUCENENET specific - lock to ensure writes don't collide for this instance
+ try
{
LineFileOut(doc).WriteLine(sb.ToString());
}
+ finally
+ {
+ UninterruptableMonitor.Exit(lineFileLock);
+ }
}
return 1;
diff --git a/src/Lucene.Net.Codecs/Memory/DirectDocValuesProducer.cs b/src/Lucene.Net.Codecs/Memory/DirectDocValuesProducer.cs
index 9c97c64..06f6305 100644
--- a/src/Lucene.Net.Codecs/Memory/DirectDocValuesProducer.cs
+++ b/src/Lucene.Net.Codecs/Memory/DirectDocValuesProducer.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -211,7 +212,8 @@ namespace Lucene.Net.Codecs.Memory
public override NumericDocValues GetNumeric(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!numericInstances.TryGetValue(field.Number, out NumericDocValues instance))
{
@@ -221,6 +223,10 @@ namespace Lucene.Net.Codecs.Memory
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private NumericDocValues LoadNumeric(NumericEntry entry)
@@ -337,7 +343,8 @@ namespace Lucene.Net.Codecs.Memory
public override BinaryDocValues GetBinary(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!binaryInstances.TryGetValue(field.Number, out BinaryDocValues instance))
{
@@ -347,6 +354,10 @@ namespace Lucene.Net.Codecs.Memory
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private BinaryDocValues LoadBinary(BinaryEntry entry)
@@ -389,7 +400,8 @@ namespace Lucene.Net.Codecs.Memory
public override SortedDocValues GetSorted(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!sortedInstances.TryGetValue(field.Number, out SortedDocValues instance))
{
@@ -399,6 +411,10 @@ namespace Lucene.Net.Codecs.Memory
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private SortedDocValues LoadSorted(FieldInfo field)
@@ -443,7 +459,8 @@ namespace Lucene.Net.Codecs.Memory
public override SortedSetDocValues GetSortedSet(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
var entry = sortedSets[field.Number];
if (!sortedSetInstances.TryGetValue(field.Number, out SortedSetRawValues instance))
@@ -460,6 +477,10 @@ namespace Lucene.Net.Codecs.Memory
// Must make a new instance since the iterator has state:
return new RandomAccessOrdsAnonymousClass(entry, docToOrdAddress, ords, values);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private class RandomAccessOrdsAnonymousClass : RandomAccessOrds
@@ -536,7 +557,8 @@ namespace Lucene.Net.Codecs.Memory
else
{
IBits instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!docsWithFieldInstances.TryGetValue(fieldNumber, out instance))
{
@@ -552,6 +574,10 @@ namespace Lucene.Net.Codecs.Memory
docsWithFieldInstances[fieldNumber] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
return instance;
}
}
diff --git a/src/Lucene.Net.Codecs/Memory/MemoryDocValuesProducer.cs b/src/Lucene.Net.Codecs/Memory/MemoryDocValuesProducer.cs
index 87f0c0c..afff0f1 100644
--- a/src/Lucene.Net.Codecs/Memory/MemoryDocValuesProducer.cs
+++ b/src/Lucene.Net.Codecs/Memory/MemoryDocValuesProducer.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Lucene.Net.Util.Fst;
using Lucene.Net.Util.Packed;
@@ -207,7 +208,8 @@ namespace Lucene.Net.Codecs.Memory
public override NumericDocValues GetNumeric(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!numericInstances.TryGetValue(field.Number, out NumericDocValues instance))
{
@@ -216,6 +218,10 @@ namespace Lucene.Net.Codecs.Memory
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override long RamBytesUsed() => ramBytesUsed;
@@ -331,7 +337,8 @@ namespace Lucene.Net.Codecs.Memory
public override BinaryDocValues GetBinary(FieldInfo field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!binaryInstances.TryGetValue(field.Number, out BinaryDocValues instance))
{
@@ -340,6 +347,10 @@ namespace Lucene.Net.Codecs.Memory
}
return instance;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
private BinaryDocValues LoadBinary(FieldInfo field)
@@ -409,7 +420,8 @@ namespace Lucene.Net.Codecs.Memory
return DocValues.EMPTY_SORTED;
}
FST<long?> instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!fstInstances.TryGetValue(field.Number, out instance))
{
@@ -419,6 +431,10 @@ namespace Lucene.Net.Codecs.Memory
fstInstances[field.Number] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
var docToOrd = GetNumeric(field);
var fst = instance;
@@ -521,7 +537,8 @@ namespace Lucene.Net.Codecs.Memory
return DocValues.EMPTY_SORTED_SET; // empty FST!
}
FST<long?> instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!fstInstances.TryGetValue(field.Number, out instance))
{
@@ -531,6 +548,10 @@ namespace Lucene.Net.Codecs.Memory
fstInstances[field.Number] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
var docToOrds = GetBinary(field);
var fst = instance;
@@ -656,7 +677,8 @@ namespace Lucene.Net.Codecs.Memory
else
{
IBits instance;
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!docsWithFieldInstances.TryGetValue(fieldNumber, out instance))
{
@@ -672,6 +694,10 @@ namespace Lucene.Net.Codecs.Memory
docsWithFieldInstances[fieldNumber] = instance;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
return instance;
}
}
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldsReader.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldsReader.cs
index bf5bf86..01e9897 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldsReader.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldsReader.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Lucene.Net.Util.Fst;
using System;
@@ -677,7 +678,8 @@ namespace Lucene.Net.Codecs.SimpleText
public override Terms GetTerms(string field)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (!_termsCache.TryGetValue(field, out SimpleTextTerms terms) || terms == null)
{
@@ -694,6 +696,10 @@ namespace Lucene.Net.Codecs.SimpleText
return terms;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override int Count => -1;
diff --git a/src/Lucene.Net.Facet/FacetsConfig.cs b/src/Lucene.Net.Facet/FacetsConfig.cs
index 735157e..83f60c1 100644
--- a/src/Lucene.Net.Facet/FacetsConfig.cs
+++ b/src/Lucene.Net.Facet/FacetsConfig.cs
@@ -1,6 +1,7 @@
// Lucene version compatibility level 4.8.1
using Lucene.Net.Diagnostics;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -141,7 +142,8 @@ namespace Lucene.Net.Facet
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual DimConfig GetDimConfig(string dimName)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (!fieldTypes.TryGetValue(dimName, out DimConfig ft))
{
@@ -149,6 +151,10 @@ namespace Lucene.Net.Facet
}
return ft;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -158,7 +164,8 @@ namespace Lucene.Net.Facet
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual void SetHierarchical(string dimName, bool v)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
@@ -170,6 +177,10 @@ namespace Lucene.Net.Facet
fieldType.IsHierarchical = v;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -179,7 +190,8 @@ namespace Lucene.Net.Facet
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual void SetMultiValued(string dimName, bool v)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
@@ -191,6 +203,10 @@ namespace Lucene.Net.Facet
fieldType.IsMultiValued = v;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -201,7 +217,8 @@ namespace Lucene.Net.Facet
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual void SetRequireDimCount(string dimName, bool v)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
@@ -213,6 +230,10 @@ namespace Lucene.Net.Facet
fieldType.RequireDimCount = v;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -222,7 +243,8 @@ namespace Lucene.Net.Facet
/// </summary>
public virtual void SetIndexFieldName(string dimName, string indexFieldName)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
@@ -234,6 +256,10 @@ namespace Lucene.Net.Facet
fieldType.IndexFieldName = indexFieldName;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs b/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
index e7a2dd5..c9a9748 100644
--- a/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
@@ -1,5 +1,6 @@
// Lucene version compatibility level 4.8.1
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
@@ -82,7 +83,8 @@ namespace Lucene.Net.Facet.Taxonomy
{
// LUCENENET NOTE: Since ConditionalWeakTable doesn't synchronize on enumeration in the RamBytesUsed() method,
// the lock is still required here despite it being a threadsafe collection.
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
object cacheKey = context.Reader.CoreCacheKey;
if (!ordsCache.TryGetValue(cacheKey, out CachedOrds ords))
@@ -97,6 +99,10 @@ namespace Lucene.Net.Facet.Taxonomy
}
return ords;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public override string IndexFieldName => source.IndexFieldName;
@@ -198,7 +204,8 @@ namespace Lucene.Net.Facet.Taxonomy
public virtual long RamBytesUsed()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
long bytes = 0;
foreach (var pair in ordsCache)
@@ -208,6 +215,10 @@ namespace Lucene.Net.Facet.Taxonomy
return bytes;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
index e15c06a..7a478e7 100644
--- a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
@@ -6,6 +6,7 @@ using Lucene.Net.Index;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -306,7 +307,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
{
if (!initializedReaderManager)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// verify that the taxo-writer hasn't been closed on us.
EnsureOpen();
@@ -317,6 +319,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
initializedReaderManager = true;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
@@ -370,7 +376,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
protected virtual void Dispose(bool disposing)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (disposing && !isClosed)
{
@@ -378,6 +385,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
DoClose();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private void DoClose()
@@ -393,7 +404,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
private void CloseResources() // LUCENENET: Made private, since this has the same purpose as Dispose(bool).
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (initializedReaderManager)
{
@@ -404,6 +416,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
cache?.Dispose();
parentStream.Dispose(); // LUCENENET specific
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -413,7 +429,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
protected virtual int FindCategory(FacetLabel categoryPath)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// If we can find the category in the cache, or we know the cache is
// complete, we can return the response directly from it
@@ -480,6 +497,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
}
return doc;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public virtual int AddCategory(FacetLabel categoryPath)
@@ -491,7 +512,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
if (res < 0)
{
// the category is not in the cache - following code cannot be executed in parallel.
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
res = FindCategory(categoryPath);
if (res < 0)
@@ -505,6 +527,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
res = InternalAddCategory(categoryPath);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
return res;
}
@@ -671,7 +697,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
private void RefreshReaderManager()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// this method is synchronized since it cannot happen concurrently with
// addCategoryDocument -- when this method returns, we must know that the
@@ -686,11 +713,16 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
shouldRefreshReaderManager = false;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public virtual void Commit()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
EnsureOpen();
// LUCENE-4972: if we always call setCommitData, we create empty commits
@@ -702,6 +734,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
}
indexWriter.Commit();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -730,7 +766,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
public virtual void PrepareCommit()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
EnsureOpen();
// LUCENE-4972: if we always call setCommitData, we create empty commits
@@ -742,6 +779,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
}
indexWriter.PrepareCommit();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public virtual int Count
@@ -784,7 +825,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
// complete or not.
private void PerhapsFillCache()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (cacheMisses < cacheMissesUntilFill)
{
@@ -849,7 +891,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
cacheIsComplete = !aborted;
if (cacheIsComplete)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock); // LUCENENET TODO: Do we need to synchroize again since the whole method is synchronized?
+ try
{
// everything is in the cache, so no need to keep readerManager open.
// this block is executed in a sync block so that it works well with
@@ -858,15 +901,24 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
readerManager = null;
initializedReaderManager = false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
private TaxonomyIndexArrays GetTaxoArrays()
{
if (taxoArrays is null)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (taxoArrays is null)
{
@@ -886,6 +938,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
return taxoArrays;
}
@@ -1118,7 +1174,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
public virtual void Rollback()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
EnsureOpen();
indexWriter.Rollback();
@@ -1130,6 +1187,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
// subclasses to provide their own dipsosable implementation.
Dispose();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
@@ -1140,7 +1201,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
/// </summary>
public virtual void ReplaceTaxonomy(Directory taxoDir)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// replace the taxonomy by doing IW optimized operations
indexWriter.DeleteAll();
@@ -1161,6 +1223,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
// update indexEpoch as a taxonomy replace is just like it has be recreated
++indexEpoch;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs b/src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs
index 556faaf..761edd2 100644
--- a/src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/TaxonomyReader.cs
@@ -1,6 +1,7 @@
// Lucene version compatibility level 4.8.1
using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -181,12 +182,17 @@ namespace Lucene.Net.Facet.Taxonomy
#pragma warning restore CA1063 // Implement IDisposable Correctly
{
if (closed) return;
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (closed) return;
DecRef();
closed = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
Dispose(true);
GC.SuppressFinalize(this);
}
diff --git a/src/Lucene.Net.Facet/Taxonomy/WriterCache/Cl2oTaxonomyWriterCache.cs b/src/Lucene.Net.Facet/Taxonomy/WriterCache/Cl2oTaxonomyWriterCache.cs
index 0239cbf..4f9f8b0 100644
--- a/src/Lucene.Net.Facet/Taxonomy/WriterCache/Cl2oTaxonomyWriterCache.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/WriterCache/Cl2oTaxonomyWriterCache.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 4.8.1
+using Lucene.Net.Support.Threading;
using System;
using System.Threading;
@@ -80,7 +81,8 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
// LUCENENET: Use additional lock to ensure our ReaderWriterLockSlim only gets
// disposed by the first caller.
- lock (disposalLock)
+ UninterruptableMonitor.Enter(disposalLock);
+ try
{
if (isDisposed) return;
syncLock.EnterWriteLock();
@@ -95,6 +97,10 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
syncLock.Dispose();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(disposalLock);
+ }
}
}
diff --git a/src/Lucene.Net.Facet/Taxonomy/WriterCache/LruTaxonomyWriterCache.cs b/src/Lucene.Net.Facet/Taxonomy/WriterCache/LruTaxonomyWriterCache.cs
index 484fc3a..9dd5d40 100644
--- a/src/Lucene.Net.Facet/Taxonomy/WriterCache/LruTaxonomyWriterCache.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/WriterCache/LruTaxonomyWriterCache.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 4.8.1
+using Lucene.Net.Support.Threading;
using System;
namespace Lucene.Net.Facet.Taxonomy.WriterCache
@@ -90,19 +91,29 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
{
get
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
return cache.Count == cache.Limit;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
public virtual void Clear()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
cache.Clear();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public void Dispose()
@@ -116,7 +127,8 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
if (disposing)
{
if (isDisposed) return;
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (isDisposed) return;
if (cache != null)
@@ -126,20 +138,30 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
}
isDisposed = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
public virtual int Get(FacetLabel categoryPath)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
return cache.TryGetValue(categoryPath, out int result) ? result : -1;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public virtual bool Put(FacetLabel categoryPath, int ordinal)
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
bool ret = cache.Put(categoryPath, ordinal);
// If the cache is full, we need to clear one or more old entries
@@ -155,6 +177,10 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
}
return ret;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Facet/Taxonomy/WriterCache/NameIntCacheLRU.cs b/src/Lucene.Net.Facet/Taxonomy/WriterCache/NameIntCacheLRU.cs
index b17e5c7..e189275 100644
--- a/src/Lucene.Net.Facet/Taxonomy/WriterCache/NameIntCacheLRU.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/WriterCache/NameIntCacheLRU.cs
@@ -1,5 +1,6 @@
// Lucene version compatibility level 4.8.1
using J2N.Collections.Concurrent;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -228,7 +229,8 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
return false;
}
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
// Double-check that another thread didn't beat us to the operation
n = cache.Count - (2 * maxCacheSize) / 3;
@@ -246,6 +248,10 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
i++;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
return true;
}
}
diff --git a/src/Lucene.Net.Grouping/AbstractFirstPassGroupingCollector.cs b/src/Lucene.Net.Grouping/AbstractFirstPassGroupingCollector.cs
index f9fca90..bd8e559 100644
--- a/src/Lucene.Net.Grouping/AbstractFirstPassGroupingCollector.cs
+++ b/src/Lucene.Net.Grouping/AbstractFirstPassGroupingCollector.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -242,11 +243,16 @@ namespace Lucene.Net.Search.Grouping
// the bottom group with this new group.
//CollectedSearchGroup<TGroupValue> bottomGroup = orderedGroups.PollLast();
CollectedSearchGroup<TGroupValue> bottomGroup;
- lock (m_orderedGroups)
+ UninterruptableMonitor.Enter(m_orderedGroups);
+ try
{
bottomGroup = m_orderedGroups.Last();
m_orderedGroups.Remove(bottomGroup);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_orderedGroups);
+ }
if (Debugging.AssertsEnabled) Debugging.Assert(m_orderedGroups.Count == topNGroups - 1);
groupMap.Remove(bottomGroup.GroupValue);
@@ -309,11 +315,16 @@ namespace Lucene.Net.Search.Grouping
CollectedSearchGroup<TGroupValue> prevLast;
if (m_orderedGroups != null)
{
- lock (m_orderedGroups)
+ UninterruptableMonitor.Enter(m_orderedGroups);
+ try
{
prevLast = m_orderedGroups.Last();
m_orderedGroups.Remove(group);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(m_orderedGroups);
+ }
if (Debugging.AssertsEnabled) Debugging.Assert(m_orderedGroups.Count == topNGroups - 1);
}
else
diff --git a/src/Lucene.Net.Misc/Document/LazyDocument.cs b/src/Lucene.Net.Misc/Document/LazyDocument.cs
index f64d0fd..82d2db9 100644
--- a/src/Lucene.Net.Misc/Document/LazyDocument.cs
+++ b/src/Lucene.Net.Misc/Document/LazyDocument.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Analysis;
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -76,7 +77,8 @@ namespace Lucene.Net.Documents
LazyField value = new LazyField(this, fieldInfo.Name, fieldInfo.Number);
values.Add(value);
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
// edge case: if someone asks this LazyDoc for more LazyFields
// after other LazyFields from the same LazyDoc have been
@@ -84,6 +86,10 @@ namespace Lucene.Net.Documents
// so the new LazyFields are also populated.
doc = null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
return value;
}
@@ -93,7 +99,8 @@ namespace Lucene.Net.Documents
/// </summary>
internal virtual Document GetDocument()
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
if (doc == null)
{
@@ -108,6 +115,10 @@ namespace Lucene.Net.Documents
}
return doc;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// :TODO: synchronize to prevent redundent copying? (sync per field name?)
diff --git a/src/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs b/src/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
index 0858294..e7c6fb6 100644
--- a/src/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
+++ b/src/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Search.Spans;
+using Lucene.Net.Support.Threading;
using System.Runtime.CompilerServices;
namespace Lucene.Net.QueryParsers.Surround.Query
@@ -69,13 +70,18 @@ namespace Lucene.Net.QueryParsers.Surround.Query
protected virtual void CheckMax()
{
- lock (_lock)
+ UninterruptableMonitor.Enter(_lock);
+ try
{
if (AtMax)
throw new TooManyBasicQueries(MaxBasicQueries);
queriesMade++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(_lock);
+ }
}
public virtual TermQuery NewTermQuery(Term term)
diff --git a/src/Lucene.Net.QueryParser/Xml/Builders/CachedFilterBuilder.cs b/src/Lucene.Net.QueryParser/Xml/Builders/CachedFilterBuilder.cs
index 825161c..27e1313 100644
--- a/src/Lucene.Net.QueryParser/Xml/Builders/CachedFilterBuilder.cs
+++ b/src/Lucene.Net.QueryParser/Xml/Builders/CachedFilterBuilder.cs
@@ -1,5 +1,6 @@
using J2N.Collections.Concurrent;
using Lucene.Net.Search;
+using Lucene.Net.Support.Threading;
using System.Xml;
namespace Lucene.Net.QueryParsers.Xml.Builders
@@ -56,7 +57,8 @@ namespace Lucene.Net.QueryParsers.Xml.Builders
public virtual Filter GetFilter(XmlElement e)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
XmlElement childElement = DOMUtils.GetFirstChildOrFail(e);
@@ -99,6 +101,10 @@ namespace Lucene.Net.QueryParsers.Xml.Builders
filterCache[cacheKey] = cachedFilter;
return cachedFilter;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
// LUCENENET NOTE: LRUCache replaced with LurchTable
diff --git a/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs b/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
index 992e361..9c5b8bf 100644
--- a/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
+++ b/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Analysis;
using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System.Xml;
@@ -65,10 +66,15 @@ namespace Lucene.Net.QueryParsers.Xml.Builders
if (unSafeParser != null)
{
//synchronize on unsafe parser
- lock (unSafeParser)
+ UninterruptableMonitor.Enter(unSafeParser);
+ try
{
q = unSafeParser.Parse(text);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(unSafeParser);
+ }
}
else
{
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
index 1129421..aee5c18 100644
--- a/src/Lucene.Net.Replicator/LocalReplicator.cs
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -1,4 +1,5 @@
using J2N.Threading.Atomic;
+using Lucene.Net.Support.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -159,18 +160,24 @@ namespace Lucene.Net.Replicator
/// <exception cref="ObjectDisposedException">This replicator has already been disposed.</exception>
protected void EnsureOpen()
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
if (!disposed)
return;
throw AlreadyClosedException.Create(this.GetType().FullName, "This replicator has already been disposed.");
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
public virtual SessionToken CheckForUpdate(string currentVersion)
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
EnsureOpen();
if (currentRevision == null)
@@ -187,6 +194,10 @@ namespace Lucene.Net.Replicator
sessions[sessionID] = new ReplicationSession(token, currentRevision);
return token;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
protected virtual void Dispose(bool disposing)
@@ -194,12 +205,17 @@ namespace Lucene.Net.Replicator
if (disposed || !disposing)
return;
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
foreach (ReplicationSession session in sessions.Values)
session.Revision.DecRef();
sessions.Clear();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
disposed = true;
}
@@ -221,18 +237,24 @@ namespace Lucene.Net.Replicator
get => expirationThreshold;
set
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
EnsureOpen();
expirationThreshold = value;
CheckExpiredSessions();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
}
public virtual Stream ObtainFile(string sessionId, string source, string fileName)
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
EnsureOpen();
@@ -249,11 +271,16 @@ namespace Lucene.Net.Replicator
sessions[sessionId].MarkAccessed();
return session.Revision.Revision.Open(source, fileName);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
public virtual void Publish(IRevision revision)
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
EnsureOpen();
@@ -281,16 +308,25 @@ namespace Lucene.Net.Replicator
CheckExpiredSessions();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
/// <exception cref="InvalidOperationException"></exception>
public virtual void Release(string sessionId)
{
- lock (padlock)
+ UninterruptableMonitor.Enter(padlock);
+ try
{
EnsureOpen();
ReleaseSession(sessionId);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(padlock);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index e0c0164..9d05757 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -91,12 +91,17 @@ namespace Lucene.Net.Replicator
/// </summary>
public void Start()
{
- lock (controlLock)
+ UninterruptableMonitor.Enter(controlLock);
+ try
{
if (IsAlive)
return;
IsAlive = true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(controlLock);
+ }
RegisterWait(interval);
}
@@ -105,12 +110,17 @@ namespace Lucene.Net.Replicator
/// </summary>
public void Stop()
{
- lock (controlLock)
+ UninterruptableMonitor.Enter(controlLock);
+ try
{
if (!IsAlive)
return;
IsAlive = false;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(controlLock);
+ }
stopHandle = new AutoResetEvent(false);
//NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
diff --git a/src/Lucene.Net.Suggest/Spell/SpellChecker.cs b/src/Lucene.Net.Suggest/Spell/SpellChecker.cs
index bbfc0ba..23c4e39 100644
--- a/src/Lucene.Net.Suggest/Spell/SpellChecker.cs
+++ b/src/Lucene.Net.Suggest/Spell/SpellChecker.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Documents;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -144,8 +145,9 @@ namespace Lucene.Net.Search.Spell
public virtual void SetSpellIndex(Directory spellIndexDir)
{
// this could be the same directory as the current spellIndex
- // modifications to the directory should be synchronized
- lock (modifyCurrentIndexLock)
+ // modifications to the directory should be synchronized
+ UninterruptableMonitor.Enter(modifyCurrentIndexLock);
+ try
{
EnsureOpen();
if (!DirectoryReader.IndexExists(spellIndexDir))
@@ -156,6 +158,10 @@ namespace Lucene.Net.Search.Spell
}
SwapSearcher(spellIndexDir);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(modifyCurrentIndexLock);
+ }
}
/// <summary>
@@ -442,7 +448,8 @@ namespace Lucene.Net.Search.Spell
/// <exception cref="ObjectDisposedException"> if the Spellchecker is already closed </exception>
public virtual void ClearIndex()
{
- lock (modifyCurrentIndexLock)
+ UninterruptableMonitor.Enter(modifyCurrentIndexLock);
+ try
{
EnsureOpen();
var dir = this.spellIndex;
@@ -452,6 +459,10 @@ namespace Lucene.Net.Search.Spell
#pragma warning restore 612, 618
SwapSearcher(dir);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(modifyCurrentIndexLock);
+ }
}
/// <summary>
@@ -485,7 +496,8 @@ namespace Lucene.Net.Search.Spell
/// <exception cref="IOException"> If there is a low-level I/O error. </exception>
public void IndexDictionary(IDictionary dict, IndexWriterConfig config, bool fullMerge)
{
- lock (modifyCurrentIndexLock)
+ UninterruptableMonitor.Enter(modifyCurrentIndexLock);
+ try
{
EnsureOpen();
Directory dir = this.spellIndex;
@@ -558,6 +570,10 @@ namespace Lucene.Net.Search.Spell
// is fetched:
SwapSearcher(dir);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(modifyCurrentIndexLock);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -634,12 +650,17 @@ namespace Lucene.Net.Search.Spell
private IndexSearcher ObtainSearcher()
{
- lock (searcherLock)
+ UninterruptableMonitor.Enter(searcherLock);
+ try
{
EnsureOpen();
searcher.IndexReader.IncRef();
return searcher;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(searcherLock);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -681,12 +702,17 @@ namespace Lucene.Net.Search.Spell
{
if (disposing && !disposed)
{
- lock (searcherLock)
+ UninterruptableMonitor.Enter(searcherLock);
+ try
{
disposed = true;
searcher?.IndexReader?.Dispose();
searcher = null;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(searcherLock);
+ }
}
}
@@ -698,7 +724,8 @@ namespace Lucene.Net.Search.Spell
* this operation than block access to the current searcher while opening.
*/
IndexSearcher indexSearcher = CreateSearcher(dir);
- lock (searcherLock)
+ UninterruptableMonitor.Enter(searcherLock);
+ try
{
if (disposed)
{
@@ -710,6 +737,10 @@ namespace Lucene.Net.Search.Spell
searcher = indexSearcher;
this.spellIndex = dir;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(searcherLock);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs b/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
index a3e5f77..3a084a3 100644
--- a/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
+++ b/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
@@ -13,6 +13,7 @@ using System.IO;
using System.Text;
using JCG = J2N.Collections.Generic;
using Directory = Lucene.Net.Store.Directory;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Search.Suggest.Analyzing
{
@@ -328,7 +329,8 @@ namespace Lucene.Net.Search.Suggest.Analyzing
if (writer != null)
return;
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
if (writer == null)
{
@@ -341,6 +343,10 @@ namespace Lucene.Net.Search.Suggest.Analyzing
m_searcherMgr = new SearcherManager(writer, true, null);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
index 76c6727..afacc7d 100644
--- a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
+++ b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Support.IO;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Lucene.Net.Util.Fst;
using System;
@@ -299,7 +300,8 @@ namespace Lucene.Net.Search.Suggest.Fst
public override bool Store(DataOutput output)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
output.WriteVInt64(count);
if (this.normalCompletion == null || normalCompletion.FST == null)
@@ -309,17 +311,26 @@ namespace Lucene.Net.Search.Suggest.Fst
normalCompletion.FST.Save(output);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override bool Load(DataInput input)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
count = input.ReadVInt64();
this.higherWeightsCompletion = new FSTCompletion(new FST<object>(input, NoOutputs.Singleton));
this.normalCompletion = new FSTCompletion(higherWeightsCompletion.FST, false, exactMatchFirst);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override long GetSizeInBytes()
diff --git a/src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs b/src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs
index 887f627..a46c9f1 100644
--- a/src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs
+++ b/src/Lucene.Net.Suggest/Suggest/Tst/TSTLookup.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;
@@ -261,23 +262,33 @@ namespace Lucene.Net.Search.Suggest.Tst
public override bool Store(DataOutput output)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
output.WriteVInt64(count);
WriteRecursively(output, root);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
public override bool Load(DataInput input)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
count = input.ReadVInt64();
root = new TernaryTreeNode();
ReadRecursively(input, root);
return true;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
index a270fe8..e04602f 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
@@ -17,6 +17,7 @@ using Assert = Lucene.Net.TestFramework.Assert;
using static Lucene.Net.Index.TermsEnum;
using J2N.Collections.Generic.Extensions;
using RandomizedTesting.Generators;
+using Lucene.Net.Support.Threading;
#if TESTFRAMEWORK_MSTEST
using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
diff --git a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
index a3e2aa0..2f92e96 100644
--- a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Index.Extensions;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using RandomizedTesting.Generators;
using System;
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
index 218abd1..3ec5ce9 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Analysis.Core;
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Analysis.Util;
using Lucene.Net.Attributes;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Analysis.ICU/Analysis/Icu/Segmentation/TestICUTokenizer.cs b/src/Lucene.Net.Tests.Analysis.ICU/Analysis/Icu/Segmentation/TestICUTokenizer.cs
index 2a40b41..892ffce 100644
--- a/src/Lucene.Net.Tests.Analysis.ICU/Analysis/Icu/Segmentation/TestICUTokenizer.cs
+++ b/src/Lucene.Net.Tests.Analysis.ICU/Analysis/Icu/Segmentation/TestICUTokenizer.cs
@@ -3,6 +3,7 @@ using ICU4N.Globalization;
using J2N.Threading;
using Lucene.Net.Analysis.Icu.TokenAttributes;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs b/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
index 8322fdf..13336eb 100644
--- a/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
+++ b/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
@@ -1,4 +1,5 @@
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Benchmarks.ByTask.Tasks
{
@@ -45,7 +46,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
private static void IncrNumSearches()
{
- lock (syncLock)
+ UninterruptableMonitor.Enter(syncLock);
+ try
{
prevLastMillis = lastMillis;
lastMillis = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
@@ -55,6 +57,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
}
numSearches++;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(syncLock);
+ }
}
public long GetElapsedMillis()
diff --git a/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs b/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
index 40e98a6..0600431 100644
--- a/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
+++ b/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
@@ -1,4 +1,5 @@
// Lucene version compatibility level 4.8.1
+using Lucene.Net.Support.Threading;
using RandomizedTesting.Generators;
using System;
using System.Threading;
@@ -69,7 +70,7 @@ namespace Lucene.Net.Facet
return base.OpenInput(name, context);
}
- internal virtual void doSleep(Random random, int length)
+ internal virtual void DoSleep(Random random, int length)
{
int sTime = length < 10 ? sleepMillis : (int)(sleepMillis * Math.Log(length));
if (random != null)
@@ -89,7 +90,7 @@ namespace Lucene.Net.Facet
/// <summary>
/// Make a private random. </summary>
- internal virtual Random forkRandom()
+ internal virtual Random ForkRandom()
{
if (random == null)
{
@@ -114,7 +115,7 @@ namespace Lucene.Net.Facet
: base("SlowIndexInput(" + ii + ")")
{
this.outerInstance = outerInstance;
- this.rand = outerInstance.forkRandom();
+ this.rand = outerInstance.ForkRandom();
this.ii = ii;
}
@@ -122,7 +123,7 @@ namespace Lucene.Net.Facet
{
if (numRead >= IO_SLEEP_THRESHOLD)
{
- outerInstance.doSleep(rand, 0);
+ outerInstance.DoSleep(rand, 0);
numRead = 0;
}
++numRead;
@@ -133,7 +134,7 @@ namespace Lucene.Net.Facet
{
if (numRead >= IO_SLEEP_THRESHOLD)
{
- outerInstance.doSleep(rand, len);
+ outerInstance.DoSleep(rand, len);
numRead = 0;
}
numRead += len;
@@ -192,14 +193,14 @@ namespace Lucene.Net.Facet
{
this.outerInstance = outerInstance;
this.io = io;
- this.rand = outerInstance.forkRandom();
+ this.rand = outerInstance.ForkRandom();
}
public override void WriteByte(byte b)
{
if (numWrote >= IO_SLEEP_THRESHOLD)
{
- outerInstance.doSleep(rand, 0);
+ outerInstance.DoSleep(rand, 0);
numWrote = 0;
}
++numWrote;
@@ -210,7 +211,7 @@ namespace Lucene.Net.Facet
{
if (numWrote >= IO_SLEEP_THRESHOLD)
{
- outerInstance.doSleep(rand, length);
+ outerInstance.DoSleep(rand, length);
numWrote = 0;
}
numWrote += length;
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
index 43fa461..f608ee9 100644
--- a/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
@@ -4,6 +4,7 @@ using J2N.Threading.Atomic;
using Lucene.Net.Attributes;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Search;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyCombined.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyCombined.cs
index 9efbb73..8504348 100644
--- a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyCombined.cs
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyCombined.cs
@@ -2,6 +2,7 @@
using J2N.Threading;
using J2N.Threading.Atomic;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
@@ -904,6 +905,7 @@ namespace Lucene.Net.Facet.Taxonomy
int lastOrd = tr.ParallelTaxonomyArrays.Parents.Length - 1;
Assert.IsNotNull(tr.GetPath(lastOrd), "path of last-ord " + lastOrd + " is not found!");
AssertChildrenArrays(tr.ParallelTaxonomyArrays, retry, retrieval[0]++);
+
Thread.Sleep(10);// don't starve refresh()'s CPU, which sleeps every 50 bytes for 1 ms
}
}
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
index d19a252..7e5569e 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -8,6 +8,7 @@ using Lucene.Net.Facet.Taxonomy.Directory;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
index de3040f..89e0412 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
index 4ec7450..f11a460 100644
--- a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Documents;
using Lucene.Net.Index;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs b/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
index 3b1db40..db6906d 100644
--- a/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
+++ b/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingInfixSuggesterTest.cs b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingInfixSuggesterTest.cs
index b66fc36..b65f88e 100644
--- a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingInfixSuggesterTest.cs
+++ b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingInfixSuggesterTest.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Core;
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Analysis.Util;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests/Index/TestAddIndexes.cs b/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
index a44c384..77a53a0 100644
--- a/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
+++ b/src/Lucene.Net.Tests/Index/TestAddIndexes.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Codecs;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
@@ -756,10 +757,15 @@ namespace Lucene.Net.Index
internal override void Handle(Exception t)
{
t.printStackTrace(Console.Out);
- lock (failures)
+ UninterruptableMonitor.Enter(failures);
+ try
{
failures.Add(t);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(failures);
+ }
}
internal override void DoBody(int j, Directory[] dirs)
@@ -856,10 +862,15 @@ namespace Lucene.Net.Index
if (!t.IsAlreadyClosedException() && !t.IsNullPointerException())
{
t.printStackTrace(Console.Out);
- lock (failures)
+ UninterruptableMonitor.Enter(failures);
+ try
{
failures.Add(t);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(failures);
+ }
}
}
}
@@ -961,10 +972,15 @@ namespace Lucene.Net.Index
if (report)
{
t.printStackTrace(Console.Out);
- lock (failures)
+ UninterruptableMonitor.Enter(failures);
+ try
{
failures.Add(t);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(failures);
+ }
}
}
}
diff --git a/src/Lucene.Net.Tests/Index/TestBagOfPositions.cs b/src/Lucene.Net.Tests/Index/TestBagOfPositions.cs
index e4005d9..ec324b7 100644
--- a/src/Lucene.Net.Tests/Index/TestBagOfPositions.cs
+++ b/src/Lucene.Net.Tests/Index/TestBagOfPositions.cs
@@ -1,6 +1,7 @@
using J2N.Collections.Generic.Extensions;
using J2N.Threading;
using Lucene.Net.Documents;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using RandomizedTesting.Generators;
using System;
diff --git a/src/Lucene.Net.Tests/Index/TestBagOfPostings.cs b/src/Lucene.Net.Tests/Index/TestBagOfPostings.cs
index fcdd33e..0965fb3 100644
--- a/src/Lucene.Net.Tests/Index/TestBagOfPostings.cs
+++ b/src/Lucene.Net.Tests/Index/TestBagOfPostings.cs
@@ -1,6 +1,7 @@
using J2N.Collections.Generic.Extensions;
using J2N.Threading;
using Lucene.Net.Documents;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Concurrent;
diff --git a/src/Lucene.Net.Tests/Index/TestConcurrentMergeScheduler.cs b/src/Lucene.Net.Tests/Index/TestConcurrentMergeScheduler.cs
index b69a02e..4f3ae80 100644
--- a/src/Lucene.Net.Tests/Index/TestConcurrentMergeScheduler.cs
+++ b/src/Lucene.Net.Tests/Index/TestConcurrentMergeScheduler.cs
@@ -3,6 +3,7 @@ using Lucene.Net.Attributes;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
diff --git a/src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs b/src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs
index 9f8de66..f353e3b 100644
--- a/src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs
+++ b/src/Lucene.Net.Tests/Index/TestDeletionPolicy.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
diff --git a/src/Lucene.Net.Tests/Index/TestDirectoryReader.cs b/src/Lucene.Net.Tests/Index/TestDirectoryReader.cs
index 5c0aa8b..42e6626 100644
--- a/src/Lucene.Net.Tests/Index/TestDirectoryReader.cs
+++ b/src/Lucene.Net.Tests/Index/TestDirectoryReader.cs
@@ -10,6 +10,7 @@ using System.Threading;
using JCG = J2N.Collections.Generic;
using Assert = Lucene.Net.TestFramework.Assert;
using Console = Lucene.Net.Util.SystemConsole;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Index
{
diff --git a/src/Lucene.Net.Tests/Index/TestDirectoryReaderReopen.cs b/src/Lucene.Net.Tests/Index/TestDirectoryReaderReopen.cs
index 1597167..64ca0c8 100644
--- a/src/Lucene.Net.Tests/Index/TestDirectoryReaderReopen.cs
+++ b/src/Lucene.Net.Tests/Index/TestDirectoryReaderReopen.cs
@@ -10,6 +10,7 @@ using System.Threading;
using JCG = J2N.Collections.Generic;
using Assert = Lucene.Net.TestFramework.Assert;
using Console = Lucene.Net.Util.SystemConsole;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Index
{
@@ -287,9 +288,14 @@ namespace Lucene.Net.Index
threads[i].Start();
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
+ {
+ UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(1000));
+ }
+ finally
{
- Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
+ UninterruptableMonitor.Exit(this);
}
for (int i = 0; i < n; i++)
@@ -418,9 +424,14 @@ namespace Lucene.Net.Index
refreshed.Dispose();
}
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
+ {
+ UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100)));
+ }
+ finally
{
- Monitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100)));
+ UninterruptableMonitor.Exit(this);
}
}
}
@@ -450,9 +461,14 @@ namespace Lucene.Net.Index
TestDirectoryReader.AssertIndexEquals(c.newReader, c.refreshedReader);
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
- Monitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100)));
+ UninterruptableMonitor.Wait(this, TimeSpan.FromMilliseconds(TestUtil.NextInt32(Random, 1, 100)));
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
}
}
}
@@ -520,7 +536,8 @@ namespace Lucene.Net.Index
internal virtual ReaderCouple RefreshReader(DirectoryReader reader, TestReopen test, int modify, bool hasChanges)
{
- lock (createReaderMutex)
+ UninterruptableMonitor.Enter(createReaderMutex);
+ try
{
DirectoryReader r = null;
if (test != null)
@@ -564,6 +581,10 @@ namespace Lucene.Net.Index
return new ReaderCouple(r, refreshed);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(createReaderMutex);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
index 3af2be4..4d28745 100644
--- a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
+++ b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
@@ -1,5 +1,6 @@
using J2N.Threading;
using J2N.Threading.Atomic;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using RandomizedTesting.Generators;
using System;
@@ -381,9 +382,6 @@ namespace Lucene.Net.Index
{
thread.Start();
}
-
- // LUCENENET: This was not in Lucene, but was once a part of this class. We may need to put this back if this test misbehaves in the future.
- //Thread.Sleep(1); // let them start
}
public static void Join(ThreadJob[] toJoin)
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
index 56ade97..bc1b84e 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
@@ -1338,7 +1338,7 @@ namespace Lucene.Net.Index
// Jenkins hits a fail we need to study where the
// interrupts struck!
Console.WriteLine("TEST: got interrupt");
- Console.WriteLine(re.ToString());
+ Console.WriteLine(GetToStringFrom(re));
Exception e = re.InnerException;
Assert.IsTrue(e is System.Threading.ThreadInterruptedException);
@@ -1355,7 +1355,7 @@ namespace Lucene.Net.Index
// // Jenkins hits a fail we need to study where the
// // interrupts struck!
// Console.WriteLine("TEST: got .NET interrupt");
- // Console.WriteLine(re.ToString());
+ // Console.WriteLine(GetToStringFrom(re));
// if (finish)
// {
@@ -1365,7 +1365,7 @@ namespace Lucene.Net.Index
catch (Exception t) when (t.IsThrowable())
{
Console.WriteLine("FAILED; unexpected exception");
- Console.WriteLine(t.ToString());
+ Console.WriteLine(GetToStringFrom(t));
failed = true;
break;
}
@@ -1388,7 +1388,6 @@ namespace Lucene.Net.Index
// clear interrupt state:
try
{
- UninterruptableMonitor.RestoreInterrupt();
Thread.Sleep(0);
}
catch (Exception ie) when (ie.IsInterruptedException())
@@ -1447,6 +1446,32 @@ namespace Lucene.Net.Index
throw RuntimeException.Create(e);
}
}
+
+ // LUCENENET specific - since the lock statement can potentially throw System.Threading.ThreadInterruptedException in .NET,
+ // we need to be vigilant about getting stack trace info from the errors during tests and retry if we get an interrupt exception.
+ /// <summary>
+ /// Safely gets the ToString() of an exception while ignoring any System.Threading.ThreadInterruptedException and retrying.
+ /// </summary>
+ private string GetToStringFrom(Exception exception)
+ {
+ // Clear interrupt state:
+ try
+ {
+ Thread.Sleep(0);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ // ignore
+ }
+ try
+ {
+ return exception.ToString();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ return GetToStringFrom(exception);
+ }
+ }
}
[Test]
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
index 7481bb2..8172648 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
@@ -982,11 +983,16 @@ namespace Lucene.Net.Index
}
catch (Exception t) when (t.IsThrowable())
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
Console.WriteLine(Thread.CurrentThread.Name + ": ERROR: hit unexpected exception");
Console.WriteLine(t.StackTrace);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
Assert.Fail();
}
}
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterMerging.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterMerging.cs
index c14ee52..376f9e8 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterMerging.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterMerging.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
@@ -305,7 +306,8 @@ namespace Lucene.Net.Index
public override void Merge(IndexWriter writer, MergeTrigger trigger, bool newMergesFound)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
while (true)
{
@@ -321,6 +323,10 @@ namespace Lucene.Net.Index
writer.Merge(merge);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void Dispose(bool disposing)
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterNRTIsCurrent.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterNRTIsCurrent.cs
index 1befc55..313d14c 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterNRTIsCurrent.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterNRTIsCurrent.cs
@@ -1,5 +1,6 @@
using J2N.Threading;
using Lucene.Net.Documents;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using RandomizedTesting.Generators;
using System;
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterOnJRECrash.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterOnJRECrash.cs
index 02894c5..74412ba 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterOnJRECrash.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterOnJRECrash.cs
@@ -106,6 +106,7 @@
// {
// try
// {
+// UninterruptableMonitor.RestoreInterrupt();
// Thread.Sleep(CrashTime);
// }
// catch (Exception e) when (e.IsInterruptedException())
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
index 9bd112c..590fb85 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
@@ -4,6 +4,7 @@ using Lucene.Net.Attributes;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
@@ -544,10 +545,15 @@ namespace Lucene.Net.Index
internal virtual void Handle(Exception t)
{
Console.WriteLine(t.StackTrace);
- lock (failures)
+ UninterruptableMonitor.Enter(failures);
+ try
{
failures.Add(t);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(failures);
+ }
}
internal virtual void LaunchThreads(int numIter)
diff --git a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
index b07e0fe..3a48b69 100644
--- a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
@@ -2,6 +2,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Attributes;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Threading;
diff --git a/src/Lucene.Net.Tests/Index/TestNeverDelete.cs b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
index e92fc98..3e8864d 100644
--- a/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
+++ b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
@@ -9,6 +9,7 @@ using System.Threading;
using JCG = J2N.Collections.Generic;
using Assert = Lucene.Net.TestFramework.Assert;
using Console = Lucene.Net.Util.SystemConsole;
+using Lucene.Net.Support.Threading;
namespace Lucene.Net.Index
{
diff --git a/src/Lucene.Net.Tests/Index/TestPayloads.cs b/src/Lucene.Net.Tests/Index/TestPayloads.cs
index e0ebb57..aff3c76 100644
--- a/src/Lucene.Net.Tests/Index/TestPayloads.cs
+++ b/src/Lucene.Net.Tests/Index/TestPayloads.cs
@@ -5,6 +5,7 @@ using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
@@ -617,30 +618,45 @@ namespace Lucene.Net.Index
internal virtual byte[] Get()
{
- lock (this) // TODO use BlockingCollection / BCL datastructures instead
+ UninterruptableMonitor.Enter(this); // TODO use BlockingCollection / BCL datastructures instead
+ try
{
var retArray = pool[0];
pool.RemoveAt(0);
return retArray;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual void Release(byte[] b)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
pool.Add(b);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
internal virtual int Count
{
get
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
return pool.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
index ae923a1..963d533 100644
--- a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
@@ -1,6 +1,7 @@
using J2N.Threading;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
diff --git a/src/Lucene.Net.Tests/Index/TestStressIndexing2.cs b/src/Lucene.Net.Tests/Index/TestStressIndexing2.cs
index d1c2d52..3155662 100644
--- a/src/Lucene.Net.Tests/Index/TestStressIndexing2.cs
+++ b/src/Lucene.Net.Tests/Index/TestStressIndexing2.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
@@ -210,10 +211,15 @@ namespace Lucene.Net.Index
for (int i = 0; i < threads.Length; i++)
{
IndexingThread th = threads[i];
- lock (th)
+ UninterruptableMonitor.Enter(th);
+ try
{
docs.PutAll(th.docs);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(th);
+ }
}
TestUtil.CheckIndex(dir);
@@ -257,10 +263,15 @@ namespace Lucene.Net.Index
for (int i = 0; i < threads.Length; i++)
{
IndexingThread th = threads[i];
- lock (th)
+ UninterruptableMonitor.Enter(th);
+ try
{
docs.PutAll(th.docs);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(th);
+ }
}
//System.out.println("TEST: checkindex");
@@ -1043,10 +1054,15 @@ namespace Lucene.Net.Index
Assert.Fail(e.ToString());
}
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
int dummy = docs.Count;
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
}
}
diff --git a/src/Lucene.Net.Tests/Index/TestStressNRT.cs b/src/Lucene.Net.Tests/Index/TestStressNRT.cs
index 4574402..b4f1ebd 100644
--- a/src/Lucene.Net.Tests/Index/TestStressNRT.cs
+++ b/src/Lucene.Net.Tests/Index/TestStressNRT.cs
@@ -3,6 +3,7 @@ using J2N.Threading.Atomic;
using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using RandomizedTesting.Generators;
using System;
@@ -206,13 +207,18 @@ namespace Lucene.Net.Index
long version;
DirectoryReader oldReader;
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
newCommittedModel = new Dictionary<int, long>(outerInstance.model); // take a snapshot
version = outerInstance.snapshotCount++;
oldReader = outerInstance.reader;
oldReader.IncRef(); // increment the reference since we will use this for reopening
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
DirectoryReader newReader;
if (rand.Next(100) < softCommitPercent)
@@ -260,7 +266,8 @@ namespace Lucene.Net.Index
oldReader.DecRef();
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
// install the new reader if it's newest (and check the current version since another reader may have already been installed)
//System.out.println(Thread.currentThread().getName() + ": newVersion=" + newReader.getVersion());
@@ -308,6 +315,10 @@ namespace Lucene.Net.Index
newReader.DecRef();
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
}
numCommitting.DecrementAndGet();
}
@@ -326,7 +337,8 @@ namespace Lucene.Net.Index
// We can't concurrently update the same document and retain our invariants of increasing values
// since we can't guarantee what order the updates will be executed.
- lock (sync)
+ UninterruptableMonitor.Enter(sync);
+ try
{
long val = outerInstance.model[id];
long nextVal = Math.Abs(val) + 1;
@@ -390,6 +402,10 @@ namespace Lucene.Net.Index
outerInstance.model[id] = nextVal;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(sync);
+ }
if (!before)
{
@@ -444,12 +460,17 @@ namespace Lucene.Net.Index
long val;
DirectoryReader r;
- lock (outerInstance)
+ UninterruptableMonitor.Enter(outerInstance);
+ try
{
val = outerInstance.committedModel[id];
r = outerInstance.reader;
r.IncRef();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(outerInstance);
+ }
if (Verbose)
{
diff --git a/src/Lucene.Net.Tests/Index/TestTransactions.cs b/src/Lucene.Net.Tests/Index/TestTransactions.cs
index cecfd33..eed8a01 100644
--- a/src/Lucene.Net.Tests/Index/TestTransactions.cs
+++ b/src/Lucene.Net.Tests/Index/TestTransactions.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.IO;
@@ -162,7 +163,8 @@ namespace Lucene.Net.Index
doFail = true;
try
{
- lock (@lock)
+ UninterruptableMonitor.Enter(@lock);
+ try
{
try
{
@@ -188,6 +190,10 @@ namespace Lucene.Net.Index
writer1.Commit();
writer2.Commit();
}
+ finally
+ {
+ UninterruptableMonitor.Exit(@lock);
+ }
}
finally
{
@@ -239,7 +245,8 @@ namespace Lucene.Net.Index
public override void DoWork()
{
IndexReader r1 = null, r2 = null;
- lock (@lock)
+ UninterruptableMonitor.Enter(@lock);
+ try
{
try
{
@@ -263,6 +270,10 @@ namespace Lucene.Net.Index
return;
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(@lock);
+ }
if (r1.NumDocs != r2.NumDocs)
{
throw RuntimeException.Create("doc counts differ: r1=" + r1.NumDocs + " r2=" + r2.NumDocs);
diff --git a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
index 441605a..8486cb8 100644
--- a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
@@ -1,6 +1,7 @@
using J2N.Threading;
using J2N.Threading.Atomic;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using RandomizedTesting.Generators;
@@ -327,10 +328,15 @@ namespace Lucene.Net.Search
private void AddMaxGen(long gen)
{
- lock (this)
+ UninterruptableMonitor.Enter(this);
+ try
{
maxGen = Math.Max(gen, maxGen);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(this);
+ }
}
protected override void DoSearching(TaskScheduler es, long stopTime)
diff --git a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
index b6740b3..3cba904 100644
--- a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
+++ b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
@@ -2,6 +2,7 @@
using Lucene.Net.Diagnostics;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.IO;
diff --git a/src/Lucene.Net.Tests/Search/TestSearcherManager.cs b/src/Lucene.Net.Tests/Search/TestSearcherManager.cs
index b072646..d26a8c3 100644
--- a/src/Lucene.Net.Tests/Search/TestSearcherManager.cs
+++ b/src/Lucene.Net.Tests/Search/TestSearcherManager.cs
@@ -2,6 +2,7 @@
using J2N.Threading.Atomic;
using Lucene.Net.Index;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using RandomizedTesting.Generators;
using System;
@@ -195,7 +196,8 @@ namespace Lucene.Net.Search
IndexSearcher s = null;
- lock (pastSearchers)
+ UninterruptableMonitor.Enter(pastSearchers);
+ try
{
while (pastSearchers.Count != 0 && Random.NextDouble() < 0.25)
{
@@ -216,6 +218,10 @@ namespace Lucene.Net.Search
}
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(pastSearchers);
+ }
if (s == null)
{
@@ -223,13 +229,18 @@ namespace Lucene.Net.Search
if (s.IndexReader.NumDocs != 0)
{
long token = lifetimeMGR.Record(s);
- lock (pastSearchers)
+ UninterruptableMonitor.Enter(pastSearchers);
+ try
{
if (!pastSearchers.Contains(token))
{
pastSearchers.Add(token);
}
}
+ finally
+ {
+ UninterruptableMonitor.Exit(pastSearchers);
+ }
}
}
diff --git a/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs b/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
index a41d341..9cdea78 100644
--- a/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
+++ b/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
@@ -6,6 +6,7 @@ using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
@@ -361,10 +362,15 @@ namespace Lucene.Net.Search
{
outerInstance.DoTestSearch();
}
- lock (success)
+ UninterruptableMonitor.Enter(success);
+ try
{
success.Set(num);
}
+ finally
+ {
+ UninterruptableMonitor.Exit(success);
+ }
}
}
diff --git a/src/Lucene.Net.Tests/Store/TestLockFactory.cs b/src/Lucene.Net.Tests/Store/TestLockFactory.cs
index e3e0e22..80278aa 100644
--- a/src/Lucene.Net.Tests/Store/TestLockFactory.cs
+++ b/src/Lucene.Net.Tests/Store/TestLockFactory.cs
@@ -1,6 +1,7 @@
using J2N.Threading;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Collections.Generic;
diff --git a/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs b/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs
index 6259402..db12e91 100644
--- a/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs
+++ b/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs
@@ -1,4 +1,5 @@
using J2N.Threading;
+using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
diff --git a/src/Lucene.Net.Tests/Util/TestSetOnce.cs b/src/Lucene.Net.Tests/Util/TestSetOnce.cs
index 1608df5..6ef60bc 100644
--- a/src/Lucene.Net.Tests/Util/TestSetOnce.cs
+++ b/src/Lucene.Net.Tests/Util/TestSetOnce.cs
@@ -1,4 +1,5 @@
using J2N.Threading;
+using Lucene.Net.Support.Threading;
using NUnit.Framework;
using System;
using System.Globalization;
[lucenenet] 02/08: SWEEP: Added
Lucene.Net.Util.ThreadInterruptedException and re-throw it in all of the
places that Lucene does.
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit b1e0eec678e3a345c807fa95999413065a93d07d
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Mar 23 03:12:11 2021 +0700
SWEEP: Added Lucene.Net.Util.ThreadInterruptedException and re-throw it in all of the places that Lucene does.
---
.../ByTask/Feeds/EnwikiContentSource.cs | 20 +++++--
src/Lucene.Net.Replicator/ReplicationClient.cs | 13 ++++-
.../Store/SlowClosingMockIndexInputWrapper.cs | 8 ++-
.../Store/SlowOpeningMockIndexInputWrapper.cs | 2 +-
.../Util/ThrottledIndexOutput.cs | 13 ++++-
src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs | 10 +++-
.../IndexAndTaxonomyReplicationClientTest.cs | 10 +++-
.../IndexReplicationClientTest.cs | 10 +++-
.../Index/TestDocumentsWriterDeleteQueue.cs | 13 +++--
.../Index/TestDocumentsWriterStallControl.cs | 4 +-
src/Lucene.Net.Tests/Index/TestIndexWriter.cs | 34 ++++++++----
.../Index/TestIndexWriterReader.cs | 14 ++++-
.../Index/TestIndexWriterWithThreads.cs | 10 +++-
.../Index/TestSnapshotDeletionPolicy.cs | 11 +++-
.../Search/TestControlledRealTimeReopenThread.cs | 14 +++--
.../Search/TestTimeLimitingCollector.cs | 12 +++-
.../ExceptionHandling/TestExceptionExtensions.cs | 2 +-
src/Lucene.Net/Index/ConcurrentMergeScheduler.cs | 32 +++++++----
.../Index/DocumentsWriterFlushControl.cs | 12 +++-
.../Index/DocumentsWriterPerThreadPool.cs | 10 +++-
.../Index/DocumentsWriterStallControl.cs | 24 +++++---
src/Lucene.Net/Index/IndexWriter.cs | 19 ++++---
.../Search/ControlledRealTimeReopenThread.cs | 20 +++++--
src/Lucene.Net/Search/IndexSearcher.cs | 3 +-
src/Lucene.Net/Search/TimeLimitingCollector.cs | 10 +++-
src/Lucene.Net/Store/Lock.cs | 10 +++-
src/Lucene.Net/Store/RateLimiter.cs | 10 +++-
.../ExceptionHandling/ExceptionExtensions.cs | 10 +++-
src/Lucene.Net/Util/ThreadInterruptedException.cs | 64 ++++++++++++++++++++++
29 files changed, 326 insertions(+), 98 deletions(-)
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
index ce71b77..1e06701 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/EnwikiContentSource.cs
@@ -77,8 +77,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
while (tuple == null && nmde == null && !threadDone && !stopped)
{
- Monitor.Wait(this);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException. Note that it could be thrown above on lock (this).
+ try
+ {
+ Monitor.Wait(this);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
if (tuple != null)
{
@@ -142,8 +148,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
{
while (tuple != null && !stopped)
{
- Monitor.Wait(this);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException. Note that it could be thrown above on lock (this).
+ try
+ {
+ Monitor.Wait(this); //wait();
+ }
+ catch (System.Threading.ThreadInterruptedException ie)
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
tuple = tmpTuple;
Monitor.Pulse(this); //notify();
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index 51c07d5..e0c0164 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -44,6 +44,8 @@ namespace Lucene.Net.Replicator
/// </remarks>
public class ReplicationClient : IDisposable
{
+ // LUCENENET TODO: Check to ensure ThreadInterruptException is being passed from the background worker to the current thread, as it is required by IndexWriter
+
//Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
private class ReplicationThread
{
@@ -430,7 +432,16 @@ namespace Lucene.Net.Replicator
// otherwise, if it's in the middle of replication, we wait for it to
// stop.
if (updateThread != null)
- updateThread.Stop();
+ {
+ try
+ {
+ updateThread.Stop();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
+ }
updateThread = null;
}
diff --git a/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs b/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
index 5e047cb..c65685d 100644
--- a/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/SlowClosingMockIndexInputWrapper.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System;
+using System.Threading;
namespace Lucene.Net.Store
{
@@ -40,7 +41,10 @@ namespace Lucene.Net.Store
{
Thread.Sleep(50);
}
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
finally
{
base.Dispose(disposing);
diff --git a/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs b/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
index d6f7ef5..684e118 100644
--- a/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
+++ b/src/Lucene.Net.TestFramework/Store/SlowOpeningMockIndexInputWrapper.cs
@@ -42,7 +42,7 @@ namespace Lucene.Net.Store
catch (Exception ignore) when (ignore.IsThrowable())
{
}
- throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
+ throw new Util.ThreadInterruptedException(ie);
}
}
}
diff --git a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
index 37590e2..4892032 100644
--- a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
+++ b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
@@ -142,9 +142,16 @@ namespace Lucene.Net.Util
return;
}
- Thread.Sleep(TimeSpan.FromMilliseconds(ms));
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
-
+ try
+ {
+ Thread.Sleep(TimeSpan.FromMilliseconds(ms));
+ }
+ catch (Exception e) when (e.IsInterruptedException())
+ {
+#pragma warning disable IDE0001 // Simplify name
+ throw new Util.ThreadInterruptedException(e);
+#pragma warning restore IDE0001 // Simplify name
+ }
}
public override long Length
diff --git a/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs b/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
index b293c99..40e98a6 100644
--- a/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
+++ b/src/Lucene.Net.Tests.Facet/SlowRAMDirectory.cs
@@ -77,8 +77,14 @@ namespace Lucene.Net.Facet
sTime = random.Next(sTime);
}
- Thread.Sleep(sTime);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Thread.Sleep(sTime);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
/// <summary>
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
index 6a43d60..d19a252 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -138,8 +138,14 @@ namespace Lucene.Net.Replicator
// introducing timeouts is not good, can easily lead to false positives.
while (client.IsUpdateThreadAlive)
{
- Thread.Sleep(100);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException.
+ try
+ {
+ Thread.Sleep(100);
+ }
+ catch (Exception e) when (e.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(e);
+ }
try
{
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
index 28450cf..de3040f 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -100,8 +100,14 @@ namespace Lucene.Net.Replicator
while (client.IsUpdateThreadAlive)
{
// give client a chance to update
- Thread.Sleep(100);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException.
+ try
+ {
+ Thread.Sleep(100);
+ }
+ catch (Exception e) when (e.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(e);
+ }
try
{
diff --git a/src/Lucene.Net.Tests/Index/TestDocumentsWriterDeleteQueue.cs b/src/Lucene.Net.Tests/Index/TestDocumentsWriterDeleteQueue.cs
index 5daaa7d..593a618 100644
--- a/src/Lucene.Net.Tests/Index/TestDocumentsWriterDeleteQueue.cs
+++ b/src/Lucene.Net.Tests/Index/TestDocumentsWriterDeleteQueue.cs
@@ -1,4 +1,4 @@
-using J2N.Threading;
+using J2N.Threading;
using J2N.Threading.Atomic;
using Lucene.Net.Search;
using Lucene.Net.Support.Threading;
@@ -318,9 +318,14 @@ namespace Lucene.Net.Index
public override void Run()
{
-
- latch.Wait();
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ latch.Wait();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
int i = 0;
while ((i = index.GetAndIncrement()) < ids.Length)
diff --git a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
index 4f5dd18..3af2be4 100644
--- a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
+++ b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
@@ -275,7 +275,7 @@ namespace Lucene.Net.Index
catch (Exception e) when (e.IsInterruptedException())
{
Console.WriteLine("[Waiter] got interrupted - wait count: " + sync.waiter.CurrentCount);
- throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
+ throw new Util.ThreadInterruptedException(e);
}
}
}
@@ -330,7 +330,7 @@ namespace Lucene.Net.Index
catch (Exception e) when (e.IsInterruptedException())
{
Console.WriteLine("[Updater] got interrupted - wait count: " + sync.waiter.CurrentCount);
- throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
+ throw new Util.ThreadInterruptedException(e);
}
// LUCENENET: Not sure why this catch block was added, but I suspect it was for debugging purposes. Commented it rather than removing it because
// there may be some value to debugging this way.
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
index 05f1b09..ce37594 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs
@@ -1316,7 +1316,7 @@ namespace Lucene.Net.Index
w.Dispose();
w = null;
//DirectoryReader.Open(dir).Dispose();
- using (var reader = DirectoryReader.Open(dir)) { }
+ using var reader = DirectoryReader.Open(dir);
// Strangely, if we interrupt a thread before
// all classes are loaded, the class loader
@@ -1330,7 +1330,7 @@ namespace Lucene.Net.Index
allowInterrupt = true;
}
}
- catch (ThreadInterruptedException re) // LUCENENET: This was a custom wrapper type named ThreadInterruptedException in Lucene, so leaving the catch block as is
+ catch (Util.ThreadInterruptedException re)
{
// NOTE: important to leave this verbosity/noise
// on!! this test doesn't repro easily so when
@@ -1339,17 +1339,28 @@ namespace Lucene.Net.Index
Console.WriteLine("TEST: got interrupt");
Console.WriteLine(re.ToString());
- // LUCENENET NOTE: Since our original exception is ThreadInterruptException instead of InterruptException
- // in .NET, our expectation is typically that the InnerException is null (but it doesn't have to be).
- // So, this assertion is not needed in .NET. And if we get to this catch block, we already know we have
- // the right exception type, so there is nothing to test here.
- //Exception e = re.InnerException;
- //Assert.IsTrue(e is ThreadInterruptedException);
+ Exception e = re.InnerException;
+ Assert.IsTrue(e is System.Threading.ThreadInterruptedException);
if (finish)
{
break;
}
}
+ //// LUCENENET specific:
+ //catch (System.Threading.ThreadInterruptedException re)
+ //{
+ // // NOTE: important to leave this verbosity/noise
+ // // on!! this test doesn't repro easily so when
+ // // Jenkins hits a fail we need to study where the
+ // // interrupts struck!
+ // Console.WriteLine("TEST: got .NET interrupt");
+ // Console.WriteLine(re.ToString());
+
+ // if (finish)
+ // {
+ // break;
+ // }
+ //}
catch (Exception t) when (t.IsThrowable())
{
Console.WriteLine("FAILED; unexpected exception");
@@ -1378,7 +1389,7 @@ namespace Lucene.Net.Index
{
Thread.Sleep(0);
}
- catch (ThreadInterruptedException)
+ catch (Exception ie) when (ie.IsInterruptedException())
{
// ignore
}
@@ -1449,7 +1460,7 @@ namespace Lucene.Net.Index
// up front... else we can see a false failure if 2nd
// interrupt arrives while class loader is trying to
// init this class (in servicing a first interrupt):
- //Assert.IsTrue((new ThreadInterruptedException(new Exception("Thread interrupted"))).InnerException is ThreadInterruptedException);
+ Assert.IsTrue(new Util.ThreadInterruptedException(new System.Threading.ThreadInterruptedException()).InnerException is System.Threading.ThreadInterruptedException);
// issue 300 interrupts to child thread
int numInterrupts = AtLeast(300);
@@ -1494,8 +1505,7 @@ namespace Lucene.Net.Index
// up front... else we can see a false failure if 2nd
// interrupt arrives while class loader is trying to
// init this class (in servicing a first interrupt):
- // C# does not have the late load problem.
- //Assert.IsTrue((new ThreadInterruptedException(new Exception("Thread interrupted"))).InnerException is ThreadInterruptedException);
+ Assert.IsTrue((new Util.ThreadInterruptedException(new System.Threading.ThreadInterruptedException())).InnerException is System.Threading.ThreadInterruptedException);
// issue 300 interrupts to child thread
int numInterrupts = AtLeast(300);
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
index b000cf5..9bd112c 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
@@ -508,12 +508,20 @@ namespace Lucene.Net.Index
{
for (int i = 0; i < outerInstance.numThreads; i++)
{
-
- threads[i].Join();
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ threads[i].Join();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+#pragma warning disable IDE0001 // Simplify name
+ throw new Util.ThreadInterruptedException(ie);
+#pragma warning restore IDE0001 // Simplify name
+ }
}
}
+
internal virtual void Close(bool doWait)
{
didClose = true;
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
index f9b0a71..65b6416 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
@@ -119,8 +119,14 @@ namespace Lucene.Net.Index
{
diskFull = true;
- Thread.Sleep(1);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Thread.Sleep(1);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
if (fullCount++ >= 5)
{
diff --git a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
index d330a09..ae923a1 100644
--- a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
@@ -226,9 +226,14 @@ namespace Lucene.Net.Index
}
}
- Thread.Sleep(1);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
-
+ try
+ {
+ Thread.Sleep(1);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
} while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
}
}
diff --git a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
index 302377d..441605a 100644
--- a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
@@ -521,12 +521,18 @@ namespace Lucene.Net.Search
public override void UpdateDocument(Term term, IEnumerable<IIndexableField> doc, Analyzer analyzer)
{
base.UpdateDocument(term, doc, analyzer);
- if (waitAfterUpdate)
+ try
+ {
+ if (waitAfterUpdate)
+ {
+ signal.Reset(signal.CurrentCount == 0 ? 0 : signal.CurrentCount - 1);
+ latch.Wait();
+ }
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
{
- signal.Reset(signal.CurrentCount == 0 ? 0 : signal.CurrentCount - 1);
- latch.Wait();
+ throw new Util.ThreadInterruptedException(ie);
}
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
}
}
diff --git a/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs b/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
index 428855b..a41d341 100644
--- a/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
+++ b/src/Lucene.Net.Tests/Search/TestTimeLimitingCollector.cs
@@ -401,8 +401,16 @@ namespace Lucene.Net.Search
int docId = doc + docBase;
if (slowdown > 0)
{
- ThreadJob.Sleep(slowdown);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ ThreadJob.Sleep(slowdown);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+#pragma warning disable IDE0001 // Simplify name
+ throw new Util.ThreadInterruptedException(ie);
+#pragma warning restore IDE0001 // Simplify name
+ }
}
if (Debugging.AssertsEnabled) Debugging.Assert(docId >= 0," base={0} doc={1}", docBase, doc);
diff --git a/src/Lucene.Net.Tests/Support/ExceptionHandling/TestExceptionExtensions.cs b/src/Lucene.Net.Tests/Support/ExceptionHandling/TestExceptionExtensions.cs
index 628b09e..2a9257f 100644
--- a/src/Lucene.Net.Tests/Support/ExceptionHandling/TestExceptionExtensions.cs
+++ b/src/Lucene.Net.Tests/Support/ExceptionHandling/TestExceptionExtensions.cs
@@ -318,7 +318,7 @@ namespace Lucene
typeof(Lucene.UnsupportedOperationException),
// Corresponds to Lucene's ThreadInterruptedException
- typeof(ThreadInterruptedException),
+ typeof(Lucene.Net.Util.ThreadInterruptedException),
// Corresponds to SecurityException
typeof(SecurityException),
diff --git a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
index e873011..16c3b00 100644
--- a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
+++ b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
@@ -434,8 +434,14 @@ namespace Lucene.Net.Index
{
Message(" too many merges; stalling...");
}
- Monitor.Wait(this);
- // LUCENENET: Just let ThreadInterruptedException propagate. Note that it could be thrown above on lock (this).
+ try
+ {
+ Monitor.Wait(this);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
if (IsVerbose)
@@ -690,15 +696,21 @@ namespace Lucene.Net.Index
/// </summary>
protected virtual void HandleMergeException(Exception exc)
{
- // When an exception is hit during merge, IndexWriter
- // removes any partial files and then allows another
- // merge to run. If whatever caused the error is not
- // transient then the exception will keep happening,
- // so, we sleep here to avoid saturating CPU in such
- // cases:
- Thread.Sleep(250);
+ try
+ {
+ // When an exception is hit during merge, IndexWriter
+ // removes any partial files and then allows another
+ // merge to run. If whatever caused the error is not
+ // transient then the exception will keep happening,
+ // so, we sleep here to avoid saturating CPU in such
+ // cases:
+ Thread.Sleep(250);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
throw new MergePolicy.MergeException(exc, m_dir);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
}
private bool suppressExceptions;
diff --git a/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs b/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
index 8a23eac..124f8b7 100644
--- a/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterFlushControl.cs
@@ -309,12 +309,18 @@ namespace Lucene.Net.Index
public void WaitForFlush()
{
- lock (this)
+ lock (this)
{
while (flushingWriters.Count != 0)
{
- Monitor.Wait(this);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Monitor.Wait(this);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
}
}
diff --git a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
index 10240f8..349af3c 100644
--- a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs
@@ -350,8 +350,14 @@ namespace Lucene.Net.Index
else
{
// Wait until a thread state frees up:
- Monitor.Wait(this);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Monitor.Wait(this);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
}
}
diff --git a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
index 77303bc..fad1ab4 100644
--- a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
+++ b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs
@@ -1,6 +1,7 @@
using J2N.Runtime.CompilerServices;
using J2N.Threading;
using Lucene.Net.Diagnostics;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
@@ -81,15 +82,20 @@ namespace Lucene.Net.Index
if (stalled) // react on the first wakeup call!
{
// don't loop here, higher level logic will re-stall!
-
- // LUCENENET: make sure not to run IncWaiters / DecrWaiters in Debugging.Assert as that gets
- // disabled in production
- var result = IncWaiters();
- if (Debugging.AssertsEnabled) Debugging.Assert(result);
- Monitor.Wait(this);
- result = DecrWaiters();
- if (Debugging.AssertsEnabled) Debugging.Assert(result);
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ // LUCENENET: make sure not to run IncWaiters / DecrWaiters in Debugging.Assert as that gets
+ // disabled in production
+ var result = IncWaiters();
+ if (Debugging.AssertsEnabled) Debugging.Assert(result);
+ Monitor.Wait(this);
+ result = DecrWaiters();
+ if (Debugging.AssertsEnabled) Debugging.Assert(result);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
}
}
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index 5daf4ba..adda7ea 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -157,8 +157,8 @@ namespace Lucene.Net.Index
/// <para><b>NOTE</b>: If you call
/// <see cref="Thread.Interrupt()"/> on a thread that's within
/// <see cref="IndexWriter"/>, <see cref="IndexWriter"/> will try to catch this (eg, if
- /// it's in a Wait() or <see cref="Thread.Sleep(int)"/>), and will then throw
- /// the unchecked exception <see cref="ThreadInterruptedException"/>
+ /// it's in a <see cref="Monitor.Wait(object)"/> or <see cref="Thread.Sleep(int)"/>), and will then throw
+ /// the unchecked exception <see cref="Util.ThreadInterruptedException"/>
/// and <b>clear</b> the interrupt status on the thread.</para>
/// </remarks>
@@ -1178,7 +1178,7 @@ namespace Lucene.Net.Index
// any pending merges are waiting:
mergeScheduler.Merge(this, MergeTrigger.CLOSING, false);
}
- catch (ThreadInterruptedException) // LUCENENET: In Lucene, they caught their custom ThreadInterruptedException here, so we are leaving this catch block as is
+ catch (Util.ThreadInterruptedException)
{
// ignore any interruption, does not matter
interrupted = true;
@@ -1198,7 +1198,7 @@ namespace Lucene.Net.Index
FinishMerges(waitForMerges && !interrupted);
break;
}
- catch (ThreadInterruptedException) // LUCENENET: In Lucene, they caught their custom ThreadInterruptedException here, so we are leaving this catch block as is
+ catch (Util.ThreadInterruptedException)
{
// by setting the interrupted status, the
// next call to finishMerges will pass false,
@@ -5329,9 +5329,14 @@ namespace Lucene.Net.Index
// fails to be called, we wait for at most 1 second
// and then return so caller can check if wait
// conditions are satisfied:
-
- Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Monitor.Wait(this, TimeSpan.FromMilliseconds(1000));
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
}
diff --git a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
index 961ea84..954c018 100644
--- a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
@@ -135,13 +135,21 @@ namespace Lucene.Net.Search
{
finish = true;
reopenCond.Set();
-
- Join();
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
- // LUCENENET specific: dispose reset event
- reopenCond.Dispose();
- available.Dispose();
+ try
+ {
+ Join();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
+ finally
+ {
+ // LUCENENET specific: dispose reset event
+ reopenCond.Dispose();
+ available.Dispose();
+ }
}
}
diff --git a/src/Lucene.Net/Search/IndexSearcher.cs b/src/Lucene.Net/Search/IndexSearcher.cs
index 50e9213..f76d991 100644
--- a/src/Lucene.Net/Search/IndexSearcher.cs
+++ b/src/Lucene.Net/Search/IndexSearcher.cs
@@ -880,8 +880,7 @@ namespace Lucene.Net.Search
}
catch (Exception e) when (e.IsInterruptedException())
{
- // LUCENENET: Throwing as same type, no need to wrap here
- throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
+ throw new Util.ThreadInterruptedException(e);
}
catch (Exception e)
{
diff --git a/src/Lucene.Net/Search/TimeLimitingCollector.cs b/src/Lucene.Net/Search/TimeLimitingCollector.cs
index 651d983..4549503 100644
--- a/src/Lucene.Net/Search/TimeLimitingCollector.cs
+++ b/src/Lucene.Net/Search/TimeLimitingCollector.cs
@@ -304,8 +304,14 @@ namespace Lucene.Net.Search
// TODO: Use System.nanoTime() when Lucene moves to Java SE 5.
counter.AddAndGet(resolution);
- Thread.Sleep(TimeSpan.FromMilliseconds(Interlocked.Read(ref resolution)));
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Thread.Sleep(TimeSpan.FromMilliseconds(Interlocked.Read(ref resolution)));
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
}
}
diff --git a/src/Lucene.Net/Store/Lock.cs b/src/Lucene.Net/Store/Lock.cs
index 4ee94d0..0f9d167 100644
--- a/src/Lucene.Net/Store/Lock.cs
+++ b/src/Lucene.Net/Store/Lock.cs
@@ -136,8 +136,14 @@ namespace Lucene.Net.Store
throw e;
}
- Thread.Sleep(TimeSpan.FromMilliseconds(LOCK_POLL_INTERVAL));
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Thread.Sleep(TimeSpan.FromMilliseconds(LOCK_POLL_INTERVAL));
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
locked = Obtain();
}
diff --git a/src/Lucene.Net/Store/RateLimiter.cs b/src/Lucene.Net/Store/RateLimiter.cs
index df7ccd0..61e2339 100644
--- a/src/Lucene.Net/Store/RateLimiter.cs
+++ b/src/Lucene.Net/Store/RateLimiter.cs
@@ -120,8 +120,14 @@ namespace Lucene.Net.Store
var pauseNS = targetNS - curNS;
if (pauseNS > 0)
{
- Thread.Sleep(TimeSpan.FromMilliseconds(pauseNS / 1000000));
- // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
+ try
+ {
+ Thread.Sleep(TimeSpan.FromMilliseconds(pauseNS / 1000000));
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
curNS = Time.NanoTime();
continue;
diff --git a/src/Lucene.Net/Support/ExceptionHandling/ExceptionExtensions.cs b/src/Lucene.Net/Support/ExceptionHandling/ExceptionExtensions.cs
index 3795b7a..5a25bf6 100644
--- a/src/Lucene.Net/Support/ExceptionHandling/ExceptionExtensions.cs
+++ b/src/Lucene.Net/Support/ExceptionHandling/ExceptionExtensions.cs
@@ -155,6 +155,10 @@ namespace Lucene
// .NET made IOException a SystemExcpetion, but those should not be included here
e.IsIOException() ||
+ // .NET made System.Threading.ThreadInterruptedException a SystemException, but we need to ignore it
+ // because InterruptedException in Java subclasses Exception, not RuntimeException
+ e is System.Threading.ThreadInterruptedException ||
+
// ObjectDisposedException is a special case because in Lucene the AlreadyClosedException derived
// from IOException and was therefore a checked excpetion type.
e is ObjectDisposedException ||
@@ -448,10 +452,10 @@ namespace Lucene
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsInterruptedException(this Exception e)
{
- // LUCENENET: Special case - we only catch under certain scenarios and do not rethrow explicitly.
// This exception is the shutdown signal for a thread and it is used in Lucene for control flow.
- // However, in .NET it is thrown in more cases than in Java. So, rather than wrapping it in a new
- // exception type, we don't catch it unless there is a specific reason to do something other than re-throw.
+ // Lucene uses a custom Lucene.Net.Util.ThreadInterruptedException exception to handle the signal.
+ // It is only thrown from certain blocks, and we use UninterruptableMonitor.Enter() to avoid getting
+ // the System.Threading.ThreadInterruptedException when obtaining locks.
return e is ThreadInterruptedException;
}
diff --git a/src/Lucene.Net/Util/ThreadInterruptedException.cs b/src/Lucene.Net/Util/ThreadInterruptedException.cs
new file mode 100644
index 0000000..85dbc89
--- /dev/null
+++ b/src/Lucene.Net/Util/ThreadInterruptedException.cs
@@ -0,0 +1,64 @@
+using System;
+#if FEATURE_SERIALIZABLE_EXCEPTIONS
+using System.Runtime.Serialization;
+#endif
+
+namespace Lucene.Net.Util
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Thrown by Lucene on detecing that <see cref="System.Threading.Thread.Interrupt()"/> had been
+ /// called. This exception has the specific purpose of being allowed to pass through to the
+ /// calling thread of <see cref="J2N.Threading.ThreadJob"/> so it reaches the appropriate handler.
+ /// </summary>
+ // LUCENENET: In Lucene, this exception was so it could be re-thrown unchecked. It has been
+ // re-purposed in .NET but used in all the same scenerios.
+ // LUCENENET: It is no longer good practice to use binary serialization.
+ // See: https://github.com/dotnet/corefx/issues/23584#issuecomment-325724568
+#if FEATURE_SERIALIZABLE_EXCEPTIONS
+ [Serializable]
+#endif
+ public class ThreadInterruptedException : Exception, IRuntimeException
+ {
+ public ThreadInterruptedException(Exception interruptedException)
+ : base(interruptedException.Message, interruptedException)
+ {
+ }
+
+ public ThreadInterruptedException(string message) : base(message)
+ {
+ }
+
+ public ThreadInterruptedException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+#if FEATURE_SERIALIZABLE_EXCEPTIONS
+ /// <summary>
+ /// Initializes a new instance of this class with serialized data.
+ /// </summary>
+ /// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
+ protected ThreadInterruptedException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+}
[lucenenet] 03/08: Lucene.Net.Support.Threading: Created
UninterruptableMonitor class to handle entering locks without throwing
System.Threading.ThreadInterruptedException (which is what happens in Java)
Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit dd89a4fcf42f76c54c44c2decae8b4811c6e43e5
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Wed Oct 13 12:35:13 2021 +0700
Lucene.Net.Support.Threading: Created UninterruptableMonitor class to handle entering locks without throwing System.Threading.ThreadInterruptedException (which is what happens in Java)
---
.../Threading/TestUninterruptableMonitor.cs | 313 +++++++++++++++++++++
.../Support/Threading/UninterruptableMonitor.cs | 167 +++++++++++
2 files changed, 480 insertions(+)
diff --git a/src/Lucene.Net.Tests/Support/Threading/TestUninterruptableMonitor.cs b/src/Lucene.Net.Tests/Support/Threading/TestUninterruptableMonitor.cs
new file mode 100644
index 0000000..8da4b04
--- /dev/null
+++ b/src/Lucene.Net.Tests/Support/Threading/TestUninterruptableMonitor.cs
@@ -0,0 +1,313 @@
+using J2N.Threading;
+using J2N.Threading.Atomic;
+using Lucene.Net.Attributes;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using RandomizedTesting.Generators;
+using System;
+using System.Threading;
+using Assert = Lucene.Net.TestFramework.Assert;
+
+namespace Lucene.Net.Support
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ [TestFixture]
+ public class TestUninterruptableMonitor : LuceneTestCase
+ {
+ private class TransactionlThreadInterrupt : ThreadJob
+ {
+ private static AtomicInt32 transactionNumber = new AtomicInt32(0);
+
+ // Share locks between threads
+ private static readonly object lock1 = new object();
+ private static readonly object lock2 = new object();
+ private static readonly object lock3 = new object();
+
+ internal volatile bool failed;
+ internal volatile bool finish;
+
+ internal volatile bool allowInterrupt = false;
+ internal volatile bool transactionInProgress = false;
+
+
+ public override void Run()
+ {
+ while (!finish)
+ {
+ try
+ {
+ TransactionalMethod();
+ TransactionalMethod();
+ InterruptableMethod();
+ TransactionalMethod();
+ InterruptableMethod();
+
+ // Make sure these don't throw System.Threading.ThreadInterruptedException
+ Assert.IsFalse(UninterruptableMonitor.IsEntered(lock1));
+ Assert.IsFalse(UninterruptableMonitor.IsEntered(lock2));
+ Assert.IsFalse(UninterruptableMonitor.IsEntered(lock3));
+
+ if (UninterruptableMonitor.TryEnter(lock1))
+ {
+ try
+ {
+ Assert.IsTrue(UninterruptableMonitor.IsEntered(lock1));
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(lock1);
+ }
+ }
+
+ allowInterrupt = true;
+ }
+ catch (Util.ThreadInterruptedException re)
+ {
+ // Success - we received the correct exception type
+ Console.WriteLine("TEST: got interrupt");
+ Console.WriteLine(GetToStringFrom(re));
+
+ Exception e = re.InnerException;
+ Assert.IsTrue(e is System.Threading.ThreadInterruptedException);
+
+ // Make sure we didn't interrupt in the middle of a transaction
+ Assert.IsFalse(transactionInProgress);
+
+ if (finish)
+ {
+ break;
+ }
+ }
+ catch (Exception t) when (t.IsThrowable())
+ {
+ Console.WriteLine("FAILED; unexpected exception");
+ Console.WriteLine(GetToStringFrom(t));
+
+ // Make sure we didn't error in the middle of a transaction
+ Assert.IsFalse(transactionInProgress);
+
+ failed = true;
+ break;
+ }
+ }
+ }
+
+
+ private void TransactionalMethod()
+ {
+ Assert.IsFalse(transactionInProgress, "The prior transaction failed to complete (was interrupted).");
+ transactionInProgress = true;
+ int transactionId = transactionNumber.IncrementAndGet();
+ if (Verbose)
+ {
+ Console.WriteLine($"transaction STARTED: {transactionId}");
+ }
+
+ // Nested lock test
+ UninterruptableMonitor.Enter(lock1);
+ try
+ {
+ if (Verbose)
+ {
+ Console.WriteLine("acquired lock1 successfully");
+ Console.WriteLine("sleeping...");
+ }
+
+ // Use SpinWait instead of Sleep to demonstrate the
+ // effect of calling Interrupt on a running thread.
+ Thread.SpinWait(1000000);
+
+ UninterruptableMonitor.Enter(lock2);
+ try
+ {
+ if (Verbose)
+ {
+ Console.WriteLine("acquired lock2 successfully");
+ Console.WriteLine("sleeping...");
+ }
+
+ // Use SpinWait instead of Sleep to demonstrate the
+ // effect of calling Interrupt on a running thread.
+ Thread.SpinWait(1000000);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(lock2);
+ }
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(lock1);
+ }
+
+ // inline lock test
+ UninterruptableMonitor.Enter(lock3);
+ try
+ {
+ if (Verbose)
+ {
+ Console.WriteLine("acquired lock3 successfully");
+ Console.WriteLine("sleeping...");
+ }
+
+ // Use SpinWait instead of Sleep to demonstrate the
+ // effect of calling Interrupt on a running thread.
+ Thread.SpinWait(1000000);
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(lock3);
+ }
+
+ if (Verbose)
+ {
+ Console.WriteLine($"transaction COMPLETED: {transactionId}");
+ }
+
+ transactionInProgress = false;
+ }
+
+ private void InterruptableMethod()
+ {
+ UninterruptableMonitor.Enter(lock1);
+ try
+ {
+ if (Verbose)
+ {
+ Console.WriteLine("acquired lock1 successfully");
+ Console.WriteLine("sleeping...");
+ }
+
+ try
+ {
+ UninterruptableMonitor.Wait(lock1, TimeSpan.FromMilliseconds(200));
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ throw new Util.ThreadInterruptedException(ie);
+ }
+ }
+ finally
+ {
+ UninterruptableMonitor.Exit(lock1);
+ }
+ }
+
+ /// <summary>
+ /// Safely gets the ToString() of an exception while ignoring any System.Threading.ThreadInterruptedException and retrying.
+ /// </summary>
+ private string GetToStringFrom(Exception exception)
+ {
+ // Clear interrupt state:
+ try
+ {
+ Thread.Sleep(0);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ // ignore
+ }
+ try
+ {
+ return exception.ToString();
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ return GetToStringFrom(exception);
+ }
+ }
+ }
+
+ [Test, LuceneNetSpecific]
+ [Slow]
+ public virtual void TestThreadInterrupt()
+ {
+ TransactionlThreadInterrupt t = new TransactionlThreadInterrupt();
+ t.IsBackground = (true);
+ t.Start();
+
+ // issue 300 interrupts to child thread
+ int numInterrupts = AtLeast(300);
+ int i = 0;
+ while (i < numInterrupts)
+ {
+ // TODO: would be nice to also sometimes interrupt the
+ // CMS merge threads too ...
+ Thread.Sleep(10);
+ if (t.allowInterrupt)
+ {
+ i++;
+ t.Interrupt();
+ }
+ if (!t.IsAlive)
+ {
+ break;
+ }
+ }
+ t.finish = true;
+ t.Join();
+
+ Assert.IsFalse(t.failed);
+ Assert.IsFalse(t.transactionInProgress);
+ }
+
+ [Test, LuceneNetSpecific]
+ [Slow]
+ public virtual void TestTwoThreadsInterrupt()
+ {
+ TransactionlThreadInterrupt t1 = new TransactionlThreadInterrupt();
+ t1.IsBackground = (true);
+ t1.Start();
+
+ TransactionlThreadInterrupt t2 = new TransactionlThreadInterrupt();
+ t2.IsBackground = (true);
+ t2.Start();
+
+ // issue 300 interrupts to child thread
+ int numInterrupts = AtLeast(300);
+ int i = 0;
+ while (i < numInterrupts)
+ {
+ // TODO: would be nice to also sometimes interrupt the
+ // CMS merge threads too ...
+ Thread.Sleep(10);
+ TransactionlThreadInterrupt t = Random.NextBoolean() ? t1 : t2;
+ if (t.allowInterrupt)
+ {
+ i++;
+ t.Interrupt();
+ }
+ if (!t1.IsAlive && !t2.IsAlive)
+ {
+ break;
+ }
+ }
+ t1.finish = true;
+ t2.finish = true;
+ t1.Join();
+ t2.Join();
+
+ Assert.IsFalse(t1.failed);
+ Assert.IsFalse(t2.failed);
+ Assert.IsFalse(t1.transactionInProgress);
+ Assert.IsFalse(t2.transactionInProgress);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Lucene.Net/Support/Threading/UninterruptableMonitor.cs b/src/Lucene.Net/Support/Threading/UninterruptableMonitor.cs
new file mode 100644
index 0000000..d145f13
--- /dev/null
+++ b/src/Lucene.Net/Support/Threading/UninterruptableMonitor.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Threading;
+
+namespace Lucene.Net.Support.Threading
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A drop-in replacement for <see cref="Monitor"/> that doesn't throw <see cref="ThreadInterruptedException"/>
+ /// when entering locks, but defers the excepetion until a wait or sleep occurs. This is to mimic the behavior in Java,
+ /// which does not throw when entering a lock.
+ /// </summary>
+ internal static class UninterruptableMonitor
+ {
+ public static void Enter(object obj, ref bool lockTaken)
+ {
+ // enter the lock and ignore any System.Threading.ThreadInterruptedException
+ try
+ {
+ Monitor.Enter(obj, ref lockTaken);
+ }
+ catch (Exception ie) when(ie.IsInterruptedException())
+ {
+ RetryEnter(obj, ref lockTaken);
+
+ // The lock has been obtained, now reset the interrupted status for the
+ // current thread
+ Thread.CurrentThread.Interrupt();
+ }
+ }
+
+ private static void RetryEnter(object obj, ref bool lockTaken)
+ {
+ try
+ {
+ // An interrupted exception may have already cleared the flag, and this will succeed without any more excpetions
+ Monitor.Enter(obj, ref lockTaken);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ // try again until we succeed, since an interrupt could have happened since it was cleared
+ RetryEnter(obj, ref lockTaken);
+ }
+ }
+
+ public static void Enter(object obj)
+ {
+ // enter the lock and ignore any System.Threading.ThreadInterruptedException
+ try
+ {
+ Monitor.Enter(obj);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ RetryEnter(obj);
+
+ // The lock has been obtained, now reset the interrupted status for the
+ // current thread
+ Thread.CurrentThread.Interrupt();
+ }
+ }
+
+ private static void RetryEnter(object obj)
+ {
+ try
+ {
+ // An interrupted exception may have already cleared the flag, and this will succeed without any more excpetions
+ Monitor.Enter(obj);
+ }
+ catch (Exception ie) when (ie.IsInterruptedException())
+ {
+ // try again until we succeed, since an interrupt could have happened since it was cleared
+ RetryEnter(obj);
+ }
+ }
+
+ public static void Exit(object obj)
+ {
+ Monitor.Exit(obj);
+ }
+
+ public static bool IsEntered(object obj)
+ {
+ return Monitor.IsEntered(obj);
+ }
+
+ public static bool TryEnter(object obj)
+ {
+ return Monitor.TryEnter(obj);
+ }
+
+ public static void TryEnter(object obj, ref bool lockTaken)
+ {
+ Monitor.TryEnter(obj, ref lockTaken);
+ }
+
+ public static bool TryEnter(object obj, int millisecondsTimeout)
+ {
+ return Monitor.TryEnter(obj, millisecondsTimeout);
+ }
+
+ public static bool TryEnter(object obj, TimeSpan timeout)
+ {
+ return Monitor.TryEnter(obj, timeout);
+ }
+
+ public static void TryEnter(object obj, int millisecondsTimeout, ref bool lockTaken)
+ {
+ Monitor.TryEnter(obj, millisecondsTimeout, ref lockTaken);
+ }
+
+ public static void TryEnter(object obj, TimeSpan timeout, ref bool lockTaken)
+ {
+ Monitor.TryEnter(obj, timeout, ref lockTaken);
+ }
+
+ public static void Pulse(object obj)
+ {
+ Monitor.Pulse(obj);
+ }
+
+ public static void PulseAll(object obj)
+ {
+ Monitor.PulseAll(obj);
+ }
+
+ public static void Wait(object obj)
+ {
+ Monitor.Wait(obj);
+ }
+
+ public static void Wait(object obj, int millisecondsTimeout)
+ {
+ Monitor.Wait(obj, millisecondsTimeout);
+ }
+
+ public static void Wait(object obj, TimeSpan timeout)
+ {
+ Monitor.Wait(obj, timeout);
+ }
+
+ public static void Wait(object obj, int millisecondsTimeout, bool exitContext)
+ {
+ Monitor.Wait(obj, millisecondsTimeout, exitContext);
+ }
+
+ public static void Wait(object obj, TimeSpan timeout, bool exitContext)
+ {
+ Monitor.Wait(obj, timeout, exitContext);
+ }
+ }
+}