11using J2N . Numerics ;
22using Lucene . Net . Diagnostics ;
33using Lucene . Net . Support ;
4+ using Lucene . Net . Support . Threading ;
45using Lucene . Net . Util ;
56using Microsoft . Win32 . SafeHandles ;
67using System ;
@@ -242,32 +243,46 @@ public IndexInputSlicerAnonymousClass(MMapDirectory outerInstance, string file,
242243 // outerInstance on every read because reads against a disposed mapping
243244 // already fail fast with AlreadyClosedException via the reclaimer.
244245 // EnsureOpen here only guards the act of opening a new slice.
245- public override IndexInput OpenSlice ( string sliceDescription , long offset , long length )
246+ public override IndexInput OpenSlice ( string ? sliceDescription , long offset , long length )
246247 {
247248 outerInstance . EnsureOpen ( ) ;
248- if ( offset < 0 || length < 0 || offset + length > mapping . Length )
249- {
250- throw new ArgumentException (
251- "slice() " + sliceDescription + " out of bounds: offset=" + offset
252- + ",length=" + length + ",fileLength=" + mapping . Length + ": " + this ) ;
253- }
249+ if ( ( ulong ) offset >= ( ulong ) mapping . Length )
250+ throw new ArgumentOutOfRangeException ( nameof ( offset ) ,
251+ $ "slice() { sliceDescription ?? "(null)" } offset out of bounds: " +
252+ $ "offset={ offset } ,length={ length } ,fileLength={ mapping . Length } : { this } ") ;
253+ if ( ( ulong ) length > ( ulong ) mapping . Length )
254+ throw new ArgumentOutOfRangeException ( nameof ( length ) ,
255+ $ "slice() { sliceDescription ?? "(null)" } length out of bounds: " +
256+ $ "offset={ offset } ,length={ length } ,fileLength={ mapping . Length } : { this } ") ;
257+ if ( ( ulong ) offset + ( ulong ) length > ( ulong ) mapping . Length )
258+ throw new ArgumentOutOfRangeException (
259+ $ "slice() { sliceDescription ?? "(null)" } parameters out of bounds: " +
260+ $ "offset={ offset } ,length={ length } ,fileLength={ mapping . Length } : { this } ") ;
261+
254262 // Slices reference the slicer's mapping; only the slicer owns and
255263 // disposes it.
256264 var input = new MMapIndexInput (
257- $ "MMapIndexInput({ sliceDescription } in path=\" { file } \" slice={ offset } :{ offset + length } )", ownsMapping : false , mapping ,
258- offset , length ,
259- outerInstance . chunkSizePower ) ;
260- lock ( issuedSlicesLock )
265+ $ "MMapIndexInput({ sliceDescription ?? "(null)" } in path=\" { file } \" slice={ offset } ..{ offset + length } )",
266+ ownsMapping : false , mapping , offset , length , outerInstance . chunkSizePower ) ;
267+
268+ UninterruptableMonitor . Enter ( issuedSlicesLock ) ;
269+ try
261270 {
262271 if ( Volatile . Read ( ref disposed ) != 0 )
263272 {
264273 // Slicer disposed after EnsureOpen but before we got the
265274 // lock; tear down what we just allocated.
266275 input . Dispose ( ) ;
267- throw AlreadyClosedException . Create ( nameof ( IndexInputSlicer ) , "this IndexInputSlicer is closed " ) ;
276+ throw AlreadyClosedException . Create ( nameof ( IndexInputSlicer ) , "this IndexInputSlicer is disposed " ) ;
268277 }
278+
269279 issuedSlices . Add ( input ) ;
270280 }
281+ finally
282+ {
283+ UninterruptableMonitor . Exit ( issuedSlicesLock ) ;
284+ }
285+
271286 return input ;
272287 }
273288
@@ -288,11 +303,17 @@ protected override void Dispose(bool disposing)
288303 if ( disposing )
289304 {
290305 IDisposable [ ] toDispose ;
291- lock ( issuedSlicesLock )
306+
307+ UninterruptableMonitor . Enter ( issuedSlicesLock ) ;
308+ try
292309 {
293310 toDispose = issuedSlices . OfType < IDisposable > ( ) . ToArray ( ) ;
294311 issuedSlices . Clear ( ) ;
295312 }
313+ finally
314+ {
315+ UninterruptableMonitor . Exit ( issuedSlicesLock ) ;
316+ }
296317
297318 IOUtils . DisposeWhileHandlingException ( toDispose ) ;
298319
@@ -534,7 +555,7 @@ private static SharedMapping CreateAttempt(string file, int chunkSizePower)
534555 chunks = MapChunks ( mmf , 0 , length , chunkSizePower ) ;
535556 return new SharedMapping ( mmf , fs , chunks , length ) ;
536557 }
537- catch ( Exception e ) when ( e . IsThrowable ( ) )
558+ catch ( Exception /* e */ ) // when (e.IsThrowable())
538559 {
539560 // Cleanup must not mask e: DisposeChunks swallows internally and
540561 // we dispose mmf/fs through the swallowing overload (not the
0 commit comments