# HG changeset patch
# User cin
# Date 2014-09-29 01:04:32
# Node ID 0363407ee75c3b0abb87eeefba68799d665c2d1b
# Parent 2c5631b43c7d6c0e7202a87693ec0a2afe6135e0
added object pool
diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj
--- a/Implab/Implab.csproj
+++ b/Implab/Implab.csproj
@@ -7,8 +7,6 @@
Library
Implab
Implab
- 8.0.30703
- 2.0
true
@@ -123,8 +121,8 @@
-
-
+
+
diff --git a/Implab/ObjectPool.cs b/Implab/ObjectPool.cs
new file mode 100644
--- /dev/null
+++ b/Implab/ObjectPool.cs
@@ -0,0 +1,85 @@
+using System;
+using Implab.Parallels;
+using System.Threading;
+
+namespace Implab {
+ public class ObjectPool : IDisposable {
+ readonly Func m_factory;
+ readonly Action m_cleanup;
+ readonly int m_size;
+ readonly MTQueue m_queue = new MTQueue();
+
+ volatile bool m_disposed;
+
+ volatile int m_count;
+
+ public ObjectPool(Func factory, Action cleanup, int size) {
+ Safe.ArgumentNotNull(factory, "factory");
+ Safe.ArgumentInRange(size, 1, size, "size");
+
+ m_factory = factory;
+ m_cleanup = cleanup;
+ m_size = size;
+ }
+
+ public ObjectPool(Func factory, Action cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
+ }
+
+ public ObjectPool(Func factory) : this(factory,null,Environment.ProcessorCount+1) {
+ }
+
+ public ObjectPoolWrapper 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 ObjectPoolWrapper(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
+ }
+}
+
diff --git a/Implab/ObjectPoolWrapper.cs b/Implab/ObjectPoolWrapper.cs
new file mode 100644
--- /dev/null
+++ b/Implab/ObjectPoolWrapper.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Implab {
+ public struct ObjectPoolWrapper : IDisposable {
+ readonly T m_value;
+ readonly ObjectPool m_pool;
+
+ internal ObjectPoolWrapper(T value, ObjectPool pool) {
+ m_value = value;
+ m_pool = pool;
+ }
+
+ public T Value {
+ get { return m_value; }
+ }
+
+ #region IDisposable implementation
+ public void Dispose() {
+ m_pool.Release(m_value);
+ }
+ #endregion
+ }
+}
+
diff --git a/Implab/SyncPool.cs b/Implab/SyncPool.cs
deleted file mode 100644
--- a/Implab/SyncPool.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using Implab.Parallels;
-using System.Threading;
-
-namespace Implab {
- /*public class SyncPool : IDisposable {
- readonly Func m_factory;
- readonly Action m_cleanup;
- readonly int m_size;
- readonly MTQueue m_queue = new MTQueue();
-
- volatile bool m_disposed;
-
- volatile int m_count;
-
- public SyncPool(Func factory, Action 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 factory, Action cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
- }
-
- public SyncPool(Func factory) : this(factory,null,Environment.ProcessorCount+1) {
- }
-
- public SyncPoolWrapper 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(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
- }*/
-}
-
diff --git a/Implab/SyncPoolWrapper.cs b/Implab/SyncPoolWrapper.cs
deleted file mode 100644
--- a/Implab/SyncPoolWrapper.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-
-namespace Implab {
- /*public struct SyncPoolWrapper : IDisposable {
- readonly T m_value;
- readonly SyncPool m_pool;
-
- internal SyncPoolWrapper(T value, SyncPool pool) {
- m_value = value;
- m_pool = pool;
- }
-
- public T Value {
- get { return m_value; }
- }
-
- #region IDisposable implementation
- public void Dispose() {
- m_pool.Release(m_value);
- }
- #endregion
- }*/
-}
-