Mercurial > pub > ImplabNet
diff Implab/ObjectPool.cs @ 85:abe260860bd6 v2
fixed JSONXmlReader disposing under ugly mono
ObjectPool is made abstract
author | cin |
---|---|
date | Tue, 30 Sep 2014 16:05:35 +0400 |
parents | 397fe8db0806 |
children | cdaaf4792c22 |
line wrap: on
line diff
--- a/Implab/ObjectPool.cs Tue Sep 30 08:20:45 2014 +0400 +++ b/Implab/ObjectPool.cs Tue Sep 30 16:05:35 2014 +0400 @@ -1,31 +1,26 @@ using System; using Implab.Parallels; using System.Threading; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Implab { - public class ObjectPool<T> : IDisposable { - readonly Func<T> m_factory; - readonly Action<T> m_cleanup; + public abstract class ObjectPool<T> : IDisposable { readonly int m_size; readonly MTQueue<T> m_queue = new MTQueue<T>(); + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + static readonly bool _isValueType = typeof(T).IsValueType; + bool m_disposed; int m_count; - public ObjectPool(Func<T> factory, Action<T> cleanup, int size) { - Safe.ArgumentNotNull(factory, "factory"); - Safe.ArgumentInRange(size, 1, size, "size"); - - m_factory = factory; - m_cleanup = cleanup; + protected ObjectPool(int size) { m_size = size; } - public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) { - } - - public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) { + protected ObjectPool() : this(Environment.ProcessorCount+1) { } public ObjectPoolWrapper<T> AllocateAuto() { @@ -35,24 +30,32 @@ public T Allocate() { if (m_disposed) - throw new ObjectDisposedException(this.ToString()); + throw new ObjectDisposedException(ToString()); T instance; if (m_queue.TryDequeue(out instance)) { Interlocked.Decrement(ref m_count); } else { - instance = m_factory(); + instance = CreateInstance(); + Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType); } return instance; } + protected abstract T CreateInstance(); + + protected virtual void CleanupInstance(T instance) { + } + public void Release(T instance) { + if ( Object.Equals(instance,default(T)) && !_isValueType) + return; + Thread.MemoryBarrier(); if (m_count < m_size && !m_disposed) { Interlocked.Increment(ref m_count); - if (m_cleanup != null) - m_cleanup(instance); + CleanupInstance(instance); m_queue.Enqueue(instance);