Skip to content

Commit 45f85ef

Browse files
committed
PR feedback: dispose of ManualResetEventSlims, misc
1 parent 59719b6 commit 45f85ef

1 file changed

Lines changed: 35 additions & 15 deletions

File tree

src/Lucene.Net.Tests/Store/TestMultiMMap.cs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Diagnostics;
99
using System.IO;
1010
using System.Linq;
11+
using System.Runtime.CompilerServices;
1112
using System.Text;
1213
using System.Threading;
1314
using System.Threading.Tasks;
@@ -45,9 +46,9 @@ namespace Lucene.Net.Store
4546
/// <summary>
4647
/// Tests MMapDirectory's MultiMMapIndexInput
4748
/// <para/>
48-
/// Because Java's ByteBuffer uses an int to address the
49-
/// values, it's necessary to access a file >
50-
/// Integer.MAX_VALUE in size using multiple byte buffers.
49+
/// Because .NET's <see cref="Span{T}"/> and <see cref="ReadOnlySpan{T}"/> use an int to address the
50+
/// values, and because we use a similar chunking approach to Lucene, it's necessary to access a file >
51+
/// <see cref="Int32.MaxValue"/> in size using multiple byte buffers.
5152
/// </summary>
5253
[TestFixture]
5354
public class TestMultiMMap : LuceneTestCase
@@ -536,14 +537,15 @@ public void TestOpenInputConcurrentFileExtension_Issue1090()
536537
using var mmapDir = new MMapDirectory(dir);
537538

538539
const long maxFileSize = 64L * 1024 * 1024; // 64 MiB safety cap
539-
var stop = new ManualResetEventSlim(false);
540+
using var stop = new ManualResetEventSlim(false);
540541
Exception writerError = null;
541542

542543
var writer = new Thread(() =>
543544
{
544545
var chunk = new byte[64];
545546
try
546547
{
548+
// ReSharper disable once AccessToDisposedClosure - thread joined below
547549
while (!stop.IsSet)
548550
{
549551
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
@@ -643,14 +645,15 @@ public void TestConcurrentCloneReadVsDispose_Issue1013()
643645
iteration++;
644646

645647
var primary = mmapDir.OpenInput(name, NewIOContext(random));
646-
var start = new ManualResetEventSlim(false);
648+
using var start = new ManualResetEventSlim(false);
647649
var threads = new Thread[readerThreads];
648650
long totalReads = 0;
649651

650652
for (int i = 0; i < readerThreads; i++)
651653
{
652654
threads[i] = new Thread(() =>
653655
{
656+
// ReSharper disable once AccessToDisposedClosure - thread joined below
654657
start.Wait();
655658
try
656659
{
@@ -659,6 +662,7 @@ public void TestConcurrentCloneReadVsDispose_Issue1013()
659662
IndexInput clone;
660663
try
661664
{
665+
// ReSharper disable once AccessToDisposedClosure - thread joined below
662666
clone = (IndexInput)primary.Clone();
663667
}
664668
catch (Exception e) when (e.IsAlreadyClosedException())
@@ -777,8 +781,8 @@ public void TestSameThreadOwnerDisposeWhileSiblingClonesRead_NoAVE()
777781
// The primary is opened, read, AND disposed all on THIS thread.
778782
var primary = mmapDir.OpenInput(name, NewIOContext(random));
779783

780-
var start = new ManualResetEventSlim(false);
781-
var stop = new ManualResetEventSlim(false);
784+
using var start = new ManualResetEventSlim(false);
785+
using var stop = new ManualResetEventSlim(false);
782786
var readers = new Thread[siblingReaders];
783787
for (int i = 0; i < readers.Length; i++)
784788
{
@@ -791,16 +795,19 @@ public void TestSameThreadOwnerDisposeWhileSiblingClonesRead_NoAVE()
791795
IndexInput clone;
792796
try
793797
{
798+
// ReSharper disable once AccessToDisposedClosure - thread joined below
794799
clone = (IndexInput)primary.Clone();
795800
}
796801
catch (Exception e) when (e.IsAlreadyClosedException())
797802
{
798803
return;
799804
}
800805

806+
// ReSharper disable once AccessToDisposedClosure - thread joined below
801807
start.Wait();
802808
try
803809
{
810+
// ReSharper disable once AccessToDisposedClosure - thread joined below
804811
while (!stop.IsSet)
805812
{
806813
clone.Seek(0);
@@ -904,18 +911,20 @@ public void TestConcurrentCloneVsDispose_RaceScenario()
904911
{
905912
iterations++;
906913
var primary = mmapDir.OpenInput(name, NewIOContext(random));
907-
var start = new ManualResetEventSlim(false);
914+
using var start = new ManualResetEventSlim(false);
908915
var cloners = new Thread[6];
909916
for (int i = 0; i < cloners.Length; i++)
910917
{
911918
cloners[i] = new Thread(() =>
912919
{
920+
// ReSharper disable once AccessToDisposedClosure - thread joined below
913921
start.Wait();
914922
try
915923
{
916924
while (true)
917925
{
918926
IndexInput c;
927+
// ReSharper disable once AccessToDisposedClosure - thread joined below
919928
try { c = (IndexInput)primary.Clone(); }
920929
catch (Exception e) when (e.IsAlreadyClosedException()) { return; }
921930
// Touch a byte on the clone — but don't read past dispose to keep the test focused on Clone itself.
@@ -998,7 +1007,7 @@ public void TestConcurrentReadVsSelfDispose_RaceScenario()
9981007
{
9991008
iterations++;
10001009
var input = mmapDir.OpenInput(name, NewIOContext(random));
1001-
var start = new ManualResetEventSlim(false);
1010+
using var start = new ManualResetEventSlim(false);
10021011
var readers = new Thread[4];
10031012
for (int i = 0; i < readers.Length; i++)
10041013
{
@@ -1009,9 +1018,11 @@ public void TestConcurrentReadVsSelfDispose_RaceScenario()
10091018
// the reclaimer on the shared mapping, not a single
10101019
// IndexInput.
10111020
IndexInput clone;
1021+
// ReSharper disable once AccessToDisposedClosure - thread joined below
10121022
try { clone = (IndexInput)input.Clone(); }
10131023
catch (Exception e) when (e.IsAlreadyClosedException()) { return; }
10141024

1025+
// ReSharper disable once AccessToDisposedClosure - thread joined below
10151026
start.Wait();
10161027
try
10171028
{
@@ -1070,7 +1081,7 @@ public void TestConcurrentSliceReadVsSlicerDispose_RaceScenario()
10701081
{
10711082
iterations++;
10721083
var slicer = mmapDir.CreateSlicer(name, NewIOContext(random));
1073-
var start = new ManualResetEventSlim(false);
1084+
using var start = new ManualResetEventSlim(false);
10741085
var readers = new Thread[4];
10751086
for (int i = 0; i < readers.Length; i++)
10761087
{
@@ -1080,10 +1091,12 @@ public void TestConcurrentSliceReadVsSlicerDispose_RaceScenario()
10801091
IndexInput slice;
10811092
try
10821093
{
1094+
// ReSharper disable once AccessToDisposedClosure - thread joined below
10831095
slice = slicer.OpenSlice("slice" + sliceIndex, 0, fileSize);
10841096
}
10851097
catch (Exception e) when (e.IsAlreadyClosedException()) { return; }
10861098

1099+
// ReSharper disable once AccessToDisposedClosure - thread joined below
10871100
start.Wait();
10881101
try
10891102
{
@@ -1511,14 +1524,15 @@ public void TestConcurrentClonesReadIdenticalBytes()
15111524
clones[i] = (IndexInput)root.Clone();
15121525
}
15131526

1514-
var start = new ManualResetEventSlim(false);
1527+
using var start = new ManualResetEventSlim(false);
15151528
var threads = new Thread[numWorkers];
15161529
for (int i = 0; i < numWorkers; i++)
15171530
{
15181531
int idx = i;
15191532
threads[i] = new Thread(() =>
15201533
{
15211534
var buf = new byte[fileSize];
1535+
// ReSharper disable once AccessToDisposedClosure - thread joined below
15221536
start.Wait();
15231537
for (int pass = 0; pass < passesPerWorker && errors.IsEmpty; pass++)
15241538
{
@@ -2296,7 +2310,7 @@ public void TestCrossThreadCloneDisposeReleasesReadRefDeterministically()
22962310
// disposes the clone from THIS thread - exercising the cross-thread
22972311
// Dispose path. Static and self-contained so the clone and reader thread
22982312
// are unreachable once this returns.
2299-
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
2313+
[MethodImpl(MethodImplOptions.NoInlining)]
23002314
private static void DisposeCloneCrossThread(MMapDirectory.MMapIndexInput parent)
23012315
{
23022316
IndexInput clone = (IndexInput)parent.Clone();
@@ -2394,11 +2408,17 @@ public void TestCloseWhileCloneReadingBlocksUntilDrainThenUnmaps()
23942408
Assert.IsTrue(chunks.Length > 1, "expected a multi-chunk mapping");
23952409

23962410
var clone = (MMapDirectory.MMapIndexInput)root.Clone();
2397-
var entered = new ManualResetEventSlim(false);
2398-
var resume = new ManualResetEventSlim(false);
2411+
using var entered = new ManualResetEventSlim(false);
2412+
using var resume = new ManualResetEventSlim(false);
23992413
// Park the clone INSIDE its read bracket (admitted, before the load
24002414
// returns) so the owner's close must observe it as an active reader.
2401-
clone.SetOnEnterForTest(() => { entered.Set(); resume.Wait(); });
2415+
clone.SetOnEnterForTest(() =>
2416+
{
2417+
// ReSharper disable once AccessToDisposedClosure - runs synchronously
2418+
entered.Set();
2419+
// ReSharper disable once AccessToDisposedClosure - runs synchronously
2420+
resume.Wait();
2421+
});
24022422

24032423
var reader = new Thread(() => { clone.Seek(0); clone.ReadByte(); })
24042424
{ IsBackground = true };

0 commit comments

Comments
 (0)