view 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 source

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
    }*/
}