Mercurial > pub > ImplabNet
diff Implab/SyncPool.cs @ 80:4f20870d0816 v2
added memory barriers
author | cin |
---|---|
date | Fri, 26 Sep 2014 03:32:34 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/SyncPool.cs Fri Sep 26 03:32:34 2014 +0400 @@ -0,0 +1,85 @@ +using System; +using Implab.Parallels; +using System.Threading; + +namespace Implab { + /*public class SyncPool<T> : IDisposable { + readonly Func<T> m_factory; + readonly Action<T> m_cleanup; + readonly int m_size; + readonly MTQueue<T> m_queue = new MTQueue<T>(); + + volatile bool m_disposed; + + volatile int m_count; + + public SyncPool(Func<T> factory, Action<T> cleanup, int size) { + Safe.ArgumentNotNull(factory, "factory"); + Safe.ArgumentInRange(size, 1, size, "size"); + + m_factory = factory; + m_cleanup = cleanup; + m_size = size; + } + + public SyncPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) { + } + + public SyncPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) { + } + + public SyncPoolWrapper<T> Allocate() { + if (m_disposed) + throw new ObjectDisposedException(this.ToString()); + + T instance; + if (m_queue.TryDequeue(out instance)) { + Interlocked.Decrement(ref m_count); + return instance; + } else { + instance = m_factory(); + } + return new SyncPoolWrapper<T>(instance, this); + } + + public void Release(T instance) { + if (m_count < m_size && !m_disposed) { + Interlocked.Increment(ref m_count); + + if (m_cleanup != null) + m_cleanup(instance); + + m_queue.Enqueue(instance); + + // пока элемент возвращался в кеш, была начата операция освобождения всего кеша + // и возможно уже законцена, в таком случае следует извлечь элемент обратно и + // освободить его. Если операция освобождения кеша еще не заврешилась, то будет + // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса. + if (m_disposed && m_queue.TryDequeue(out instance)) + Safe.Dispose(instance); + + } else { + Safe.Dispose(instance); + } + } + + protected virtual void Dispose(bool disposing) { + if (disposing) { + m_disposed = true; + T instance; + while (m_queue.TryDequeue(out instance)) + Safe.Dispose(instance); + } + } + + #region IDisposable implementation + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + }*/ +} +