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:49 UTC
[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.
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));
+ }
}
}