DefaultPool
using Castle.Core;
using Castle.Core.Internal;
using Castle.MicroKernel.Context;
using System;
using System.Collections.Generic;
namespace Castle.MicroKernel.Lifestyle.Pool
{
[Serializable]
public class DefaultPool : IPool, IDisposable
{
private readonly Stack<Burden> available;
private readonly IComponentActivator componentActivator;
private readonly Dictionary<object, Burden> inUse = new Dictionary<object, Burden>();
private readonly int initialSize;
private readonly int maxsize;
private readonly Lock rwlock = Lock.Create();
private bool initialized;
public DefaultPool(int initialSize, int maxsize, IComponentActivator componentActivator)
{
available = new Stack<Burden>(initialSize);
this.initialSize = initialSize;
this.maxsize = maxsize;
this.componentActivator = componentActivator;
}
public virtual void Dispose()
{
initialized = false;
foreach (Burden item in available) {
item.Release();
}
inUse.Clear();
available.Clear();
}
public virtual bool Release(object instance)
{
ILockHolder val = rwlock.ForWriting();
try {
Burden value;
if (!initialized) {
if (inUse.TryGetValue(instance, out value))
inUse.Remove(instance);
} else {
if (!inUse.TryGetValue(instance, out value))
return false;
inUse.Remove(instance);
if (available.Count < maxsize) {
if (instance is IRecyclable)
(instance as IRecyclable).Recycle();
available.Push(value);
return false;
}
}
} finally {
((IDisposable)val)?.Dispose();
}
componentActivator.Destroy(instance);
return true;
}
public virtual object Request(CreationContext context, Func<CreationContext, Burden> creationCallback)
{
ILockHolder val = rwlock.ForWriting();
Burden burden = default(Burden);
try {
if (!initialized)
Intitialize(creationCallback, context);
if (available.Count != 0) {
burden = available.Pop();
context.AttachExistingBurden(burden);
} else
burden = creationCallback(context);
try {
inUse.Add(burden.Instance, burden);
} catch (NullReferenceException) {
throw new PoolException("creationCallback didn't return a valid burden");
} catch (ArgumentNullException) {
throw new PoolException("burden returned by creationCallback does not have root instance associated with it (its Instance property is null).");
}
} finally {
((IDisposable)val)?.Dispose();
}
return burden.Instance;
}
protected virtual void Intitialize(Func<CreationContext, Burden> createCallback, CreationContext c)
{
initialized = true;
for (int i = 0; i < initialSize; i++) {
Burden item = createCallback(c);
available.Push(item);
}
}
}
}