Mercurial > pub > ImplabNet
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 84:34bb2f32634d | 85:abe260860bd6 |
|---|---|
| 1 using System; | 1 using System; |
| 2 using Implab.Parallels; | 2 using Implab.Parallels; |
| 3 using System.Threading; | 3 using System.Threading; |
| 4 using System.Diagnostics; | |
| 5 using System.Diagnostics.CodeAnalysis; | |
| 4 | 6 |
| 5 namespace Implab { | 7 namespace Implab { |
| 6 public class ObjectPool<T> : IDisposable { | 8 public abstract class ObjectPool<T> : IDisposable { |
| 7 readonly Func<T> m_factory; | |
| 8 readonly Action<T> m_cleanup; | |
| 9 readonly int m_size; | 9 readonly int m_size; |
| 10 readonly MTQueue<T> m_queue = new MTQueue<T>(); | 10 readonly MTQueue<T> m_queue = new MTQueue<T>(); |
| 11 | |
| 12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] | |
| 13 static readonly bool _isValueType = typeof(T).IsValueType; | |
| 11 | 14 |
| 12 bool m_disposed; | 15 bool m_disposed; |
| 13 | 16 |
| 14 int m_count; | 17 int m_count; |
| 15 | 18 |
| 16 public ObjectPool(Func<T> factory, Action<T> cleanup, int size) { | 19 protected ObjectPool(int size) { |
| 17 Safe.ArgumentNotNull(factory, "factory"); | |
| 18 Safe.ArgumentInRange(size, 1, size, "size"); | |
| 19 | |
| 20 m_factory = factory; | |
| 21 m_cleanup = cleanup; | |
| 22 m_size = size; | 20 m_size = size; |
| 23 } | 21 } |
| 24 | 22 |
| 25 public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) { | 23 protected ObjectPool() : this(Environment.ProcessorCount+1) { |
| 26 } | |
| 27 | |
| 28 public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) { | |
| 29 } | 24 } |
| 30 | 25 |
| 31 public ObjectPoolWrapper<T> AllocateAuto() { | 26 public ObjectPoolWrapper<T> AllocateAuto() { |
| 32 | 27 |
| 33 return new ObjectPoolWrapper<T>(Allocate(), this); | 28 return new ObjectPoolWrapper<T>(Allocate(), this); |
| 34 } | 29 } |
| 35 | 30 |
| 36 public T Allocate() { | 31 public T Allocate() { |
| 37 if (m_disposed) | 32 if (m_disposed) |
| 38 throw new ObjectDisposedException(this.ToString()); | 33 throw new ObjectDisposedException(ToString()); |
| 39 | 34 |
| 40 T instance; | 35 T instance; |
| 41 if (m_queue.TryDequeue(out instance)) { | 36 if (m_queue.TryDequeue(out instance)) { |
| 42 Interlocked.Decrement(ref m_count); | 37 Interlocked.Decrement(ref m_count); |
| 43 } else { | 38 } else { |
| 44 instance = m_factory(); | 39 instance = CreateInstance(); |
| 40 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType); | |
| 45 } | 41 } |
| 46 return instance; | 42 return instance; |
| 47 } | 43 } |
| 48 | 44 |
| 45 protected abstract T CreateInstance(); | |
| 46 | |
| 47 protected virtual void CleanupInstance(T instance) { | |
| 48 } | |
| 49 | |
| 49 public void Release(T instance) { | 50 public void Release(T instance) { |
| 51 if ( Object.Equals(instance,default(T)) && !_isValueType) | |
| 52 return; | |
| 53 | |
| 50 Thread.MemoryBarrier(); | 54 Thread.MemoryBarrier(); |
| 51 if (m_count < m_size && !m_disposed) { | 55 if (m_count < m_size && !m_disposed) { |
| 52 Interlocked.Increment(ref m_count); | 56 Interlocked.Increment(ref m_count); |
| 53 | 57 |
| 54 if (m_cleanup != null) | 58 CleanupInstance(instance); |
| 55 m_cleanup(instance); | |
| 56 | 59 |
| 57 m_queue.Enqueue(instance); | 60 m_queue.Enqueue(instance); |
| 58 | 61 |
| 59 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша | 62 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша |
| 60 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и | 63 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и |
