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);