Skip to content

Commit

Permalink
Fixes CA1063: Implement IDisposable Properly (except for IndexWriter)…
Browse files Browse the repository at this point in the history
…. Partially addresses apache#265.
  • Loading branch information
NightOwl888 committed Nov 9, 2020
1 parent 7f52580 commit 0dce38e
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 68 deletions.
2 changes: 1 addition & 1 deletion src/Lucene.Net.Demo/Facet/DistanceFacetsExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Lucene.Net.Demo.Facet
/// Shows simple usage of dynamic range faceting, using the
/// expressions module to calculate distance.
/// </summary>
public class DistanceFacetsExample : IDisposable
public sealed class DistanceFacetsExample : IDisposable
{
/// <summary>
/// Using a constant for all functionality related to a specific index
Expand Down
2 changes: 1 addition & 1 deletion src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace Lucene.Net.Demo.Facet
/// <summary>
/// Shows simple usage of dynamic range faceting.
/// </summary>
public class RangeFacetsExample : IDisposable
public sealed class RangeFacetsExample : IDisposable
{
/// <summary>
/// Using a constant for all functionality related to a specific index
Expand Down
33 changes: 20 additions & 13 deletions src/Lucene.Net.Suggest/Spell/SpellChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ namespace Lucene.Net.Search.Spell
/// </summary>
public class SpellChecker : IDisposable
{

/// <summary>
/// The default minimum score to use, if not specified by setting <see cref="Accuracy"/>
/// or overriding with <see cref="SuggestSimilar(string, int, IndexReader, string, SuggestMode, float)"/> .
Expand Down Expand Up @@ -650,25 +649,36 @@ private void EnsureOpen()
{
if (disposed)
{
throw new ObjectDisposedException(this.GetType().FullName, "Spellchecker has been closed");
throw new ObjectDisposedException(this.GetType().FullName, "Spellchecker has been disposed.");
}
}

/// <summary>
/// Dispose the underlying IndexSearcher used by this SpellChecker </summary>
/// Dispose the underlying <see cref="IndexSearcher"/> used by this <see cref="SpellChecker"/>. </summary>
/// <exception cref="IOException"> if the close operation causes an <see cref="IOException"/> </exception>
/// <exception cref="ObjectDisposedException"> if the <see cref="SpellChecker"/> is already disposed </exception>
public void Dispose()
{
if (!disposed)
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases resources used by the <see cref="SpellChecker"/> and
/// if overridden in a derived class, optionally releases unmanaged resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>

// LUCENENET specific - implemented proper dispose pattern
protected virtual void Dispose(bool disposing)
{
if (disposing && !disposed)
{
lock (searcherLock)
{
disposed = true;
if (searcher != null)
{
searcher.IndexReader.Dispose();
}
searcher?.IndexReader?.Dispose();
searcher = null;
}
}
Expand All @@ -687,12 +697,9 @@ private void SwapSearcher(Directory dir)
if (disposed)
{
indexSearcher.IndexReader.Dispose();
throw new ObjectDisposedException(this.GetType().FullName, "Spellchecker has been closed");
}
if (searcher != null)
{
searcher.IndexReader.Dispose();
throw new ObjectDisposedException(this.GetType().FullName, "Spellchecker has been disposed.");
}
searcher?.IndexReader?.Dispose();
// set the spellindex in the sync block - ensure consistency.
searcher = indexSearcher;
this.spellIndex = dir;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace Lucene.Net.Codecs.Compressing
/// <para/>
/// @lucene.experimental
/// </summary>
public sealed class CompressingTermVectorsReader : TermVectorsReader, IDisposable
public sealed class CompressingTermVectorsReader : TermVectorsReader // LUCENENET specific - removed IDisposable, it is already implemented in base class
{
private readonly FieldInfos fieldInfos;
internal readonly CompressingStoredFieldsIndexReader indexReader;
Expand Down
2 changes: 1 addition & 1 deletion src/Lucene.Net/Codecs/DocValuesProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected internal DocValuesProducer()
/// <summary>
/// Disposes all resources used by this object.
/// </summary>
public virtual void Dispose()
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace Lucene.Net.Codecs.Lucene40
/// @lucene.internal
/// </summary>
/// <seealso cref="Lucene40StoredFieldsFormat"/>
public sealed class Lucene40StoredFieldsReader : StoredFieldsReader, IDisposable
public sealed class Lucene40StoredFieldsReader : StoredFieldsReader // LUCENENET specific - removed IDisposable, it is already implemented in base class
#if FEATURE_CLONEABLE
, System.ICloneable
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace Lucene.Net.Codecs.Lucene40
/// It reads .tvd, .tvf, and .tvx files.
/// </summary>
/// <seealso cref="Lucene40TermVectorsFormat"/>
public class Lucene40TermVectorsReader : TermVectorsReader, IDisposable
public class Lucene40TermVectorsReader : TermVectorsReader // LUCENENET specific - removed IDisposable, it is already implemented in base class
{
internal const sbyte STORE_POSITIONS_WITH_TERMVECTOR = 0x1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Lucene.Net.Codecs.Lucene45

/// <summary>
/// Writer for <see cref="Lucene45DocValuesFormat"/> </summary>
public class Lucene45DocValuesConsumer : DocValuesConsumer, IDisposable
public class Lucene45DocValuesConsumer : DocValuesConsumer // LUCENENET specific - removed IDisposable, it is already implemented in base class
{
internal static readonly int BLOCK_SIZE = 16384;
internal static readonly int ADDRESS_INTERVAL = 16;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace Lucene.Net.Codecs.Lucene45

/// <summary>
/// Reader for <see cref="Lucene45DocValuesFormat"/>. </summary>
public class Lucene45DocValuesProducer : DocValuesProducer, IDisposable
public class Lucene45DocValuesProducer : DocValuesProducer // LUCENENET specific - removed IDisposable, it is already implemented in base class
{
private readonly IDictionary<int, NumericEntry> numerics;
private readonly IDictionary<int, BinaryEntry> binaries;
Expand Down
52 changes: 36 additions & 16 deletions src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,25 +113,45 @@ private void RefreshDone()
reopenCond.Reset();
}

/// <summary>
/// Releases all resources used by the <see cref="ControlledRealTimeReopenThread{T}"/>.
/// </summary>
public void Dispose()
{
finish = true;
reopenCond.Set();
//#if FEATURE_THREAD_INTERRUPT
// try
// {
//#endif
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases resources used by the <see cref="ControlledRealTimeReopenThread{T}"/> and
/// if overridden in a derived class, optionally releases unmanaged resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>

// LUCENENET specific - implemented proper dispose pattern
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
finish = true;
reopenCond.Set();
//#if FEATURE_THREAD_INTERRUPT
// try
// {
//#endif
Join();
//#if FEATURE_THREAD_INTERRUPT // LUCENENET NOTE: Senseless to catch and rethrow the same exception type
// }
// catch (ThreadInterruptedException ie)
// {
// throw new ThreadInterruptedException(ie.ToString(), ie);
// }
//#endif
// LUCENENET specific: dispose reset event
reopenCond.Dispose();
available.Dispose();
//#if FEATURE_THREAD_INTERRUPT // LUCENENET NOTE: Senseless to catch and rethrow the same exception type
// }
// catch (ThreadInterruptedException ie)
// {
// throw new ThreadInterruptedException(ie.ToString(), ie);
// }
//#endif
// LUCENENET specific: dispose reset event
reopenCond.Dispose();
available.Dispose();
}
}

/// <summary>
Expand Down
23 changes: 21 additions & 2 deletions src/Lucene.Net/Search/LiveFieldValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ namespace Lucene.Net.Search
/// the same time by two threads, because in this case you
/// cannot in general know which thread "won".
/// </summary>

public abstract class LiveFieldValues<S, T> : ReferenceManager.IRefreshListener, IDisposable
where S : class
{
Expand All @@ -49,9 +48,29 @@ public LiveFieldValues(ReferenceManager<S> mgr, T missingValue)
mgr.AddListener(this);
}

/// <summary>
/// Releases all resources used by the <see cref="LiveFieldValues{S, T}"/>.
/// </summary>
public void Dispose()
{
mgr.RemoveListener(this);
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases resources used by the <see cref="LiveFieldValues{S, T}"/> and
/// if overridden in a derived class, optionally releases unmanaged resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>

// LUCENENET specific - implemented proper dispose pattern
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
mgr.RemoveListener(this);
}
}

public virtual void BeforeRefresh()
Expand Down
27 changes: 16 additions & 11 deletions src/Lucene.Net/Search/ReferenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,8 @@ the reference. */
/// If the underlying reader of the current reference could not be disposed </exception>
public void Dispose()
{
lock (this)
{
Dispose(true);
GC.SuppressFinalize(this);
}
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
Expand All @@ -167,17 +164,25 @@ public void Dispose()
protected abstract int GetRefCount(G reference);

/// <summary>
/// Called after <see cref="Dispose()"/>, so subclass can free any resources. </summary>
/// Called after <see cref="Dispose()"/>, so subclass can free any resources.
/// <para/>
/// When overriding, be sure to include a call to <c>base.Dispose(disposing)</c> in your implementation.</summary>
/// <exception cref="IOException"> if the after dispose operation in a sub-class throws an <see cref="IOException"/>
/// </exception>
protected virtual void Dispose(bool disposing)
{
if (disposing && current != null)
if (disposing)
{
// make sure we can call this more than once
// closeable javadoc says:
// if this is already closed then invoking this method has no effect.
SwapReference(null);
lock (this)
{
if (current != null)
{
// make sure we can call this more than once
// closeable javadoc says:
// if this is already closed then invoking this method has no effect.
SwapReference(null);
}
}
}
}

Expand Down
48 changes: 32 additions & 16 deletions src/Lucene.Net/Search/SearcherLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,27 +312,43 @@ public virtual void Prune(IPruner pruner)
/// otherwise it's possible not all searcher references
/// will be freed.
/// </summary>
public virtual void Dispose()
public void Dispose()
{
lock (this)
{
_closed = true;
IList<SearcherTracker> toClose = new List<SearcherTracker>(_searchers.Values.Select(item => item.Value));
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases resources used by the <see cref="SearcherLifetimeManager"/> and
/// if overridden in a derived class, optionally releases unmanaged resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>

// Remove up front in case exc below, so we don't
// over-decRef on double-close:
foreach (var tracker in toClose)
// LUCENENET specific - implemented proper dispose pattern
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
lock (this)
{
Lazy<SearcherTracker> _;
_searchers.TryRemove(tracker.Version, out _);
}
_closed = true;
IList<SearcherTracker> toClose = new List<SearcherTracker>(_searchers.Values.Select(item => item.Value));

// Remove up front in case exc below, so we don't
// over-decRef on double-close:
foreach (var tracker in toClose)
{
_searchers.TryRemove(tracker.Version, out Lazy<SearcherTracker> _);
}

IOUtils.Dispose(toClose);
IOUtils.Dispose(toClose);

// Make some effort to catch mis-use:
if (_searchers.Count != 0)
{
throw new InvalidOperationException("another thread called record while this SearcherLifetimeManager instance was being closed; not all searchers were closed");
// Make some effort to catch mis-use:
if (_searchers.Count != 0)
{
throw new InvalidOperationException("another thread called record while this SearcherLifetimeManager instance was being disposed; not all searchers were disposed");
}
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions src/Lucene.Net/Store/OutputStreamDataOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,29 @@ public override void WriteBytes(byte[] b, int offset, int length)
_writer.Write(b, offset, length);
}

public virtual void Dispose()
/// <summary>
/// Releases all resources used by the <see cref="OutputStreamDataOutput"/>.
/// </summary>
public void Dispose()
{
_writer.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases resources used by the <see cref="OutputStreamDataOutput"/> and
/// if overridden in a derived class, optionally releases unmanaged resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>

// LUCENENET specific - implemented proper dispose pattern
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_writer.Dispose();
}
}
}
}

0 comments on commit 0dce38e

Please sign in to comment.