Skip to content
This repository has been archived by the owner on May 21, 2022. It is now read-only.

Commit

Permalink
further refinements for validaobject
Browse files Browse the repository at this point in the history
  • Loading branch information
pomma89 committed Jun 24, 2017
1 parent 6e2bf8a commit 9980cc9
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 77 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### v3.0.4 (2017-06-24) ###

* Removed dependency on Thrower.
* Removed CannotResetStateException class, not needed with new validation step.

### v3.0.3 (2017-04-08) ###

Expand Down
43 changes: 0 additions & 43 deletions src/CodeProject.ObjectPool/Core/CannotResetStateException.cs

This file was deleted.

57 changes: 31 additions & 26 deletions src/CodeProject.ObjectPool/PooledObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,31 @@ public abstract class PooledObject : IDisposable, IEquatable<PooledObject>
#region Internal Methods - resource and state management

/// <summary>
/// Validates pooled object state.
/// Validates pooled object state. An invalid object will not get into the pool and it will
/// not be returned to consumers.
/// </summary>
/// <param name="validationContext">The validation context.</param>
/// <returns>True if current pooled object is valid, false otherwise.</returns>
protected internal virtual bool ValidateObject(PooledObjectValidationContext validationContext) => true;
internal bool ValidateObject(PooledObjectValidationContext validationContext)
{
if (OnValidateObject != null)
{
try
{
return OnValidateObject(validationContext);
}
catch (Exception ex)
{
#if !NET35
if (Log.IsWarnEnabled()) Log.WarnException("[ObjectPool] An unexpected error occurred while validating an object", ex);
#else
System.Diagnostics.Debug.Assert(ex != null); // Placeholder to avoid warnings
#endif
return false;
}
}
return true;
}

/// <summary>
/// Releases the object resources. This method will be called by the pool manager when
Expand All @@ -70,10 +90,7 @@ internal bool ReleaseResources()
catch (Exception ex)
{
#if !NET35
if (Log.IsWarnEnabled())
{
Log.WarnException("[ObjectPool] An unexpected error occurred while releasing resources", ex);
}
if (Log.IsWarnEnabled()) Log.WarnException("[ObjectPool] An unexpected error occurred while releasing resources", ex);
#else
System.Diagnostics.Debug.Assert(ex != null); // Placeholder to avoid warnings
#endif
Expand All @@ -99,25 +116,10 @@ internal bool ResetState()
{
OnResetState();
}
catch (CannotResetStateException crsex)
{
#if !NET35
if (Log.IsDebugEnabled())
{
Log.DebugException("[ObjectPool] Object state could not be reset", crsex);
}
#else
System.Diagnostics.Debug.Assert(crsex != null); // Placeholder to avoid warnings
#endif
return false;
}
catch (Exception ex)
{
#if !NET35
if (Log.IsWarnEnabled())
{
Log.WarnException("[ObjectPool] An unexpected error occurred while resetting state", ex);
}
if (Log.IsWarnEnabled()) Log.WarnException("[ObjectPool] An unexpected error occurred while resetting state", ex);
#else
System.Diagnostics.Debug.Assert(ex != null); // Placeholder to avoid warnings
#endif
Expand All @@ -131,6 +133,12 @@ internal bool ResetState()

#region Events - extending resource and state management

/// <summary>
/// Validates pooled object state. An invalid object will not get into the pool and it will
/// not be returned to consumers.
/// </summary>
public Func<PooledObjectValidationContext, bool> OnValidateObject { get; set; }

/// <summary>
/// Reset the object state to allow this object to be re-used by other parts of the application.
/// </summary>
Expand Down Expand Up @@ -171,10 +179,7 @@ private void HandleReAddingToPool(bool reRegisterForFinalization)
catch (Exception ex)
{
#if !NET35
if (Log.IsWarnEnabled())
{
Log.WarnException("[ObjectPool] An error occurred while re-adding to pool", ex);
}
if (Log.IsWarnEnabled()) Log.WarnException("[ObjectPool] An error occurred while re-adding to pool", ex);
#else
System.Diagnostics.Debug.Assert(ex != null); // Placeholder to avoid warnings
#endif
Expand Down
44 changes: 39 additions & 5 deletions src/CodeProject.ObjectPool/Specialized/PooledMemoryStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,29 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using CodeProject.ObjectPool.Core;
using System;
using System.IO;

#if !NET35

using CodeProject.ObjectPool.Logging;

#endif

namespace CodeProject.ObjectPool.Specialized
{
/// <summary>
/// Pooled object prepared to work with <see cref="System.IO.MemoryStream"/> instances.
/// </summary>
public class PooledMemoryStream : PooledObject
{
#region Logging

#if !NET35
private static readonly ILog Log = LogProvider.GetLogger(typeof(PooledMemoryStream));
#endif

#endregion Logging

/// <summary>
/// The tracked memory stream.
/// </summary>
Expand All @@ -48,23 +61,44 @@ public PooledMemoryStream(int capacity)
Parent = this
};

OnResetState += () =>
OnValidateObject += (ctx) =>
{
if (ctx.Direction == PooledObjectDirection.Outbound)
{
// We validate only inbound objects, because when they are in the pool they
// cannot change their state.
return true;
}

if (!_trackedMemoryStream.CanRead || !_trackedMemoryStream.CanWrite || !_trackedMemoryStream.CanSeek)
{
throw new CannotResetStateException($"Memory stream has already been disposed");
#if !NET35
if (Log.IsWarnEnabled()) Log.Warn("[ObjectPool] Memory stream has already been disposed");
#endif
return false;
}

var memoryStreamPool = PooledObjectInfo.Handle as IMemoryStreamPool;
if (_trackedMemoryStream.Capacity < memoryStreamPool.MinimumMemoryStreamCapacity)
{
throw new CannotResetStateException($"Memory stream capacity is {_trackedMemoryStream.Capacity}, while minimum required capacity is {memoryStreamPool.MinimumMemoryStreamCapacity}");
#if !NET35
if (Log.IsWarnEnabled()) Log.Warn($"[ObjectPool] Memory stream capacity is {_trackedMemoryStream.Capacity}, while minimum required capacity is {memoryStreamPool.MinimumMemoryStreamCapacity}");
#endif
return false;
}
if (_trackedMemoryStream.Capacity > memoryStreamPool.MaximumMemoryStreamCapacity)
{
throw new CannotResetStateException($"Memory stream capacity is {_trackedMemoryStream.Capacity}, while maximum allowed capacity is {memoryStreamPool.MaximumMemoryStreamCapacity}");
#if !NET35
if (Log.IsWarnEnabled()) Log.Warn($"[ObjectPool] Memory stream capacity is {_trackedMemoryStream.Capacity}, while maximum allowed capacity is {memoryStreamPool.MaximumMemoryStreamCapacity}");
#endif
return false;
}

return true; // Object is valid.
};

OnResetState += () =>
{
_trackedMemoryStream.Position = 0L;
_trackedMemoryStream.SetLength(0L);
};
Expand Down
34 changes: 31 additions & 3 deletions src/CodeProject.ObjectPool/Specialized/PooledStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,29 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using CodeProject.ObjectPool.Core;
using System;
using System.Text;

#if !NET35

using CodeProject.ObjectPool.Logging;

#endif

namespace CodeProject.ObjectPool.Specialized
{
/// <summary>
/// Pooled object prepared to work with <see cref="StringBuilder"/> instances.
/// </summary>
public class PooledStringBuilder : PooledObject
{
#region Logging

#if !NET35
private static readonly ILog Log = LogProvider.GetLogger(typeof(PooledStringBuilder));
#endif

#endregion Logging

/// <summary>
/// The string builder.
/// </summary>
Expand All @@ -45,14 +58,29 @@ public PooledStringBuilder(int capacity)
{
StringBuilder = new StringBuilder(capacity);

OnResetState += () =>
OnValidateObject += (ctx) =>
{
if (ctx.Direction == PooledObjectDirection.Outbound)
{
// We validate only inbound objects, because when they are in the pool they
// cannot change their state.
return true;
}

var stringBuilderPool = PooledObjectInfo.Handle as IStringBuilderPool;
if (StringBuilder.Capacity > stringBuilderPool.MaximumStringBuilderCapacity)
{
throw new CannotResetStateException($"String builder capacity is {StringBuilder.Capacity}, while maximum allowed capacity is {stringBuilderPool.MaximumStringBuilderCapacity}");
#if !NET35
if (Log.IsWarnEnabled()) Log.Warn($"[ObjectPool] String builder capacity is {StringBuilder.Capacity}, while maximum allowed capacity is {stringBuilderPool.MaximumStringBuilderCapacity}");
#endif
return false;
}

return true; // Object is valid.
};

OnResetState += () =>
{
ClearStringBuilder();
};

Expand Down

0 comments on commit 9980cc9

Please sign in to comment.