Mercurial > pub > ImplabNet
comparison Implab/SyncPool.cs @ 80:4f20870d0816 v2
added memory barriers
| author | cin |
|---|---|
| date | Fri, 26 Sep 2014 03:32:34 +0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 79:05e6468f066f | 80:4f20870d0816 |
|---|---|
| 1 using System; | |
| 2 using Implab.Parallels; | |
| 3 using System.Threading; | |
| 4 | |
| 5 namespace Implab { | |
| 6 /*public class SyncPool<T> : IDisposable { | |
| 7 readonly Func<T> m_factory; | |
| 8 readonly Action<T> m_cleanup; | |
| 9 readonly int m_size; | |
| 10 readonly MTQueue<T> m_queue = new MTQueue<T>(); | |
| 11 | |
| 12 volatile bool m_disposed; | |
| 13 | |
| 14 volatile int m_count; | |
| 15 | |
| 16 public SyncPool(Func<T> factory, Action<T> cleanup, 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; | |
| 23 } | |
| 24 | |
| 25 public SyncPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) { | |
| 26 } | |
| 27 | |
| 28 public SyncPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) { | |
| 29 } | |
| 30 | |
| 31 public SyncPoolWrapper<T> Allocate() { | |
| 32 if (m_disposed) | |
| 33 throw new ObjectDisposedException(this.ToString()); | |
| 34 | |
| 35 T instance; | |
| 36 if (m_queue.TryDequeue(out instance)) { | |
| 37 Interlocked.Decrement(ref m_count); | |
| 38 return instance; | |
| 39 } else { | |
| 40 instance = m_factory(); | |
| 41 } | |
| 42 return new SyncPoolWrapper<T>(instance, this); | |
| 43 } | |
| 44 | |
| 45 public void Release(T instance) { | |
| 46 if (m_count < m_size && !m_disposed) { | |
| 47 Interlocked.Increment(ref m_count); | |
| 48 | |
| 49 if (m_cleanup != null) | |
| 50 m_cleanup(instance); | |
| 51 | |
| 52 m_queue.Enqueue(instance); | |
| 53 | |
| 54 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша | |
| 55 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и | |
| 56 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет | |
| 57 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса. | |
| 58 if (m_disposed && m_queue.TryDequeue(out instance)) | |
| 59 Safe.Dispose(instance); | |
| 60 | |
| 61 } else { | |
| 62 Safe.Dispose(instance); | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 protected virtual void Dispose(bool disposing) { | |
| 67 if (disposing) { | |
| 68 m_disposed = true; | |
| 69 T instance; | |
| 70 while (m_queue.TryDequeue(out instance)) | |
| 71 Safe.Dispose(instance); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 #region IDisposable implementation | |
| 76 | |
| 77 public void Dispose() { | |
| 78 Dispose(true); | |
| 79 GC.SuppressFinalize(this); | |
| 80 } | |
| 81 | |
| 82 #endregion | |
| 83 }*/ | |
| 84 } | |
| 85 |
