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

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master' into dev-po…
Browse files Browse the repository at this point in the history
…mma89
  • Loading branch information
pomma89 committed Jun 26, 2017
2 parents a0ab7e4 + 671d0ed commit 7fc1a1b
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 77 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Changelog for CodeProject.ObjectPool #

### v3.0.4 (2017-06-24) ###
### v3.1.0 (2017-06-24) ###

* Removed dependency on Thrower.
* Pooled objects can now specify a validation step (PR#4 by uliian).
* Removed CannotResetStateException class, not needed with new validation step.

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

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## Summary ##

* Latest release version: `v3.0.4`
* Latest release version: `v3.1.0`
* Build status on [AppVeyor](https://ci.appveyor.com): [![Build status](https://ci.appveyor.com/api/projects/status/r4qnqaqj9ri6cicn?svg=true)](https://ci.appveyor.com/project/pomma89/objectpool)
* [Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html) documentation:
+ [HTML](http://pomma89.altervista.org/objectpool/doc/html/index.html)
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#---------------------------------#

# version format
version: 3.0.4.{build}
version: 3.1.0.{build}

# branches to build
branches:
Expand All @@ -25,7 +25,7 @@ branches:
assembly_info:
patch: true
file: AssemblyInfo.*
assembly_version: "3.0.4.{build}"
assembly_version: "3.1.0.{build}"
assembly_file_version: "{version}"
assembly_informational_version: "{version}"

Expand Down
2 changes: 1 addition & 1 deletion src/CodeProject.ObjectPool/CodeProject.ObjectPool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyName>CodeProject.ObjectPool</AssemblyName>
<AssemblyTitle>Generic and concurrent Object Pool</AssemblyTitle>
<VersionPrefix>3.0.4</VersionPrefix>
<VersionPrefix>3.1.0</VersionPrefix>
<TargetFrameworks>netstandard1.0;netstandard1.3;net35;net40;net45</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyOriginatorKeyFile>../../pomma89.snk</AssemblyOriginatorKeyFile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// File name: CannotResetStateException.cs
// File name: PooledObjectDirection.cs
//
// Author(s): Alessio Parma <alessio.parma@gmail.com>
//
Expand All @@ -21,23 +21,21 @@
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;

namespace CodeProject.ObjectPool.Core
{
/// <summary>
/// This exception can be used to signal that the object whose state is being reset cannot be
/// added back to the pool for some reason.
/// Direction of a pooled object.
/// </summary>
public sealed class CannotResetStateException : Exception
public enum PooledObjectDirection
{
/// <summary>
/// Builds the exception using given message.
/// An object is returning to the pool.
/// </summary>
Inbound,

/// <summary>
/// An object is getting out of the pool.
/// </summary>
/// <param name="message">The message.</param>
public CannotResetStateException(string message)
: base(message)
{
}
Outbound
}
}
52 changes: 52 additions & 0 deletions src/CodeProject.ObjectPool/Core/PooledObjectValidationContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// File name: PooledObjectValidationContext.cs
//
// Author(s): Alessio Parma <alessio.parma@gmail.com>
//
// The MIT License (MIT)
//
// Copyright (c) 2013-2018 Alessio Parma <alessio.parma@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
// associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

namespace CodeProject.ObjectPool.Core
{
/// <summary>
/// Contains additional info which might be useful when performing an object validation step.
/// </summary>
public sealed class PooledObjectValidationContext
{
/// <summary>
/// Used when an object is returning to the pool.
/// </summary>
internal static PooledObjectValidationContext Inbound { get; } = new PooledObjectValidationContext
{
Direction = PooledObjectDirection.Inbound
};

/// <summary>
/// Used when an object is going out of the pool.
/// </summary>
internal static PooledObjectValidationContext Outbound { get; } = new PooledObjectValidationContext
{
Direction = PooledObjectDirection.Outbound
};

/// <summary>
/// Whether an object is going out of the pool or into the pool.
/// </summary>
public PooledObjectDirection Direction { get; private set; }
}
}
38 changes: 22 additions & 16 deletions src/CodeProject.ObjectPool/ObjectPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,24 +176,30 @@ public void Clear()
/// <returns>A monitored object from the pool.</returns>
public T GetObject()
{
if (PooledObjects.TryDequeue(out T pooledObject))
while (true)
{
// Object found in pool.
if (Diagnostics.Enabled) Diagnostics.IncrementPoolObjectHitCount();
}
else
{
// This should not happen normally, but could be happening when there is stress on
// the pool. No available objects in pool, create a new one and return it to the caller.
if (Diagnostics.Enabled) Diagnostics.IncrementPoolObjectMissCount();
pooledObject = CreatePooledObject();
}

// Change the state of the pooled object, marking it as reserved. We will mark it as
// available as soon as the object will return to the pool.
pooledObject.PooledObjectInfo.State = PooledObjectState.Reserved;
if (PooledObjects.TryDequeue(out T pooledObject))
{
// Object found in pool.
if (Diagnostics.Enabled) Diagnostics.IncrementPoolObjectHitCount();
}
else
{
// This should not happen normally, but could be happening when there is stress
// on the pool. No available objects in pool, create a new one and return it to
// the caller.
if (Diagnostics.Enabled) Diagnostics.IncrementPoolObjectMissCount();
pooledObject = CreatePooledObject();
}
if (pooledObject.ValidateObject(PooledObjectValidationContext.Outbound))
{
// Change the state of the pooled object, marking it as reserved. We will mark it
// as available as soon as the object will return to the pool.
pooledObject.PooledObjectInfo.State = PooledObjectState.Reserved;

return pooledObject;
return pooledObject;
}
}
}

void IObjectPoolHandle.ReturnObjectToPool(PooledObject objectToReturnToPool, bool reRegisterForFinalization)
Expand Down
79 changes: 44 additions & 35 deletions src/CodeProject.ObjectPool/PooledObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

using CodeProject.ObjectPool.Core;
using System;
using System.Collections.Generic;

#if !NET35

Expand Down Expand Up @@ -48,15 +47,40 @@ public abstract class PooledObject : IDisposable, IEquatable<PooledObject>

#region Internal Methods - 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>
/// <param name="validationContext">The validation context.</param>
/// <returns>True if current pooled object is valid, false otherwise.</returns>
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
/// there is no need for this object anymore (decreasing pooled objects count, pool is
/// being destroyed).
/// </summary>
internal bool ReleaseResources()
{
var successFlag = true;

if (OnReleaseResources != null)
{
try
Expand All @@ -66,18 +90,14 @@ 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
successFlag = false;
return false;
}
}

return successFlag;
return true;
}

/// <summary>
Expand All @@ -86,47 +106,39 @@ internal bool ReleaseResources()
/// </summary>
internal bool ResetState()
{
var successFlag = true;

if (!ValidateObject(PooledObjectValidationContext.Inbound))
{
return false;
}
if (OnResetState != null)
{
try
{
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
successFlag = 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
successFlag = false;
return false;
}
}

return successFlag;
return true;
}

#endregion Internal Methods - resource and state management

#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 @@ -167,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
Loading

0 comments on commit 7fc1a1b

Please sign in to comment.