annotate Implab/ObjectPool.cs @ 83:397fe8db0806 v2

fixed object pool
author cin
date Mon, 29 Sep 2014 15:49:15 +0400
parents 0363407ee75c
children abe260860bd6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
82
0363407ee75c added object pool
cin
parents:
diff changeset
1 using System;
0363407ee75c added object pool
cin
parents:
diff changeset
2 using Implab.Parallels;
0363407ee75c added object pool
cin
parents:
diff changeset
3 using System.Threading;
0363407ee75c added object pool
cin
parents:
diff changeset
4
0363407ee75c added object pool
cin
parents:
diff changeset
5 namespace Implab {
0363407ee75c added object pool
cin
parents:
diff changeset
6 public class ObjectPool<T> : IDisposable {
0363407ee75c added object pool
cin
parents:
diff changeset
7 readonly Func<T> m_factory;
0363407ee75c added object pool
cin
parents:
diff changeset
8 readonly Action<T> m_cleanup;
0363407ee75c added object pool
cin
parents:
diff changeset
9 readonly int m_size;
0363407ee75c added object pool
cin
parents:
diff changeset
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
0363407ee75c added object pool
cin
parents:
diff changeset
11
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
12 bool m_disposed;
82
0363407ee75c added object pool
cin
parents:
diff changeset
13
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
14 int m_count;
82
0363407ee75c added object pool
cin
parents:
diff changeset
15
0363407ee75c added object pool
cin
parents:
diff changeset
16 public ObjectPool(Func<T> factory, Action<T> cleanup, int size) {
0363407ee75c added object pool
cin
parents:
diff changeset
17 Safe.ArgumentNotNull(factory, "factory");
0363407ee75c added object pool
cin
parents:
diff changeset
18 Safe.ArgumentInRange(size, 1, size, "size");
0363407ee75c added object pool
cin
parents:
diff changeset
19
0363407ee75c added object pool
cin
parents:
diff changeset
20 m_factory = factory;
0363407ee75c added object pool
cin
parents:
diff changeset
21 m_cleanup = cleanup;
0363407ee75c added object pool
cin
parents:
diff changeset
22 m_size = size;
0363407ee75c added object pool
cin
parents:
diff changeset
23 }
0363407ee75c added object pool
cin
parents:
diff changeset
24
0363407ee75c added object pool
cin
parents:
diff changeset
25 public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
0363407ee75c added object pool
cin
parents:
diff changeset
26 }
0363407ee75c added object pool
cin
parents:
diff changeset
27
0363407ee75c added object pool
cin
parents:
diff changeset
28 public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) {
0363407ee75c added object pool
cin
parents:
diff changeset
29 }
0363407ee75c added object pool
cin
parents:
diff changeset
30
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
31 public ObjectPoolWrapper<T> AllocateAuto() {
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
32
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
33 return new ObjectPoolWrapper<T>(Allocate(), this);
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
34 }
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
35
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
36 public T Allocate() {
82
0363407ee75c added object pool
cin
parents:
diff changeset
37 if (m_disposed)
0363407ee75c added object pool
cin
parents:
diff changeset
38 throw new ObjectDisposedException(this.ToString());
0363407ee75c added object pool
cin
parents:
diff changeset
39
0363407ee75c added object pool
cin
parents:
diff changeset
40 T instance;
0363407ee75c added object pool
cin
parents:
diff changeset
41 if (m_queue.TryDequeue(out instance)) {
0363407ee75c added object pool
cin
parents:
diff changeset
42 Interlocked.Decrement(ref m_count);
0363407ee75c added object pool
cin
parents:
diff changeset
43 } else {
0363407ee75c added object pool
cin
parents:
diff changeset
44 instance = m_factory();
0363407ee75c added object pool
cin
parents:
diff changeset
45 }
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
46 return instance;
82
0363407ee75c added object pool
cin
parents:
diff changeset
47 }
0363407ee75c added object pool
cin
parents:
diff changeset
48
0363407ee75c added object pool
cin
parents:
diff changeset
49 public void Release(T instance) {
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
50 Thread.MemoryBarrier();
82
0363407ee75c added object pool
cin
parents:
diff changeset
51 if (m_count < m_size && !m_disposed) {
0363407ee75c added object pool
cin
parents:
diff changeset
52 Interlocked.Increment(ref m_count);
0363407ee75c added object pool
cin
parents:
diff changeset
53
0363407ee75c added object pool
cin
parents:
diff changeset
54 if (m_cleanup != null)
0363407ee75c added object pool
cin
parents:
diff changeset
55 m_cleanup(instance);
0363407ee75c added object pool
cin
parents:
diff changeset
56
0363407ee75c added object pool
cin
parents:
diff changeset
57 m_queue.Enqueue(instance);
0363407ee75c added object pool
cin
parents:
diff changeset
58
0363407ee75c added object pool
cin
parents:
diff changeset
59 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
0363407ee75c added object pool
cin
parents:
diff changeset
60 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
0363407ee75c added object pool
cin
parents:
diff changeset
61 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
0363407ee75c added object pool
cin
parents:
diff changeset
62 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
63 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
64 ((IDisposable)instance).Dispose() ;
82
0363407ee75c added object pool
cin
parents:
diff changeset
65
0363407ee75c added object pool
cin
parents:
diff changeset
66 } else {
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
67 if (instance is IDisposable)
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
68 ((IDisposable)instance).Dispose();
82
0363407ee75c added object pool
cin
parents:
diff changeset
69 }
0363407ee75c added object pool
cin
parents:
diff changeset
70 }
0363407ee75c added object pool
cin
parents:
diff changeset
71
0363407ee75c added object pool
cin
parents:
diff changeset
72 protected virtual void Dispose(bool disposing) {
0363407ee75c added object pool
cin
parents:
diff changeset
73 if (disposing) {
0363407ee75c added object pool
cin
parents:
diff changeset
74 m_disposed = true;
0363407ee75c added object pool
cin
parents:
diff changeset
75 T instance;
0363407ee75c added object pool
cin
parents:
diff changeset
76 while (m_queue.TryDequeue(out instance))
83
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
77 if (instance is IDisposable)
397fe8db0806 fixed object pool
cin
parents: 82
diff changeset
78 ((IDisposable)instance).Dispose();
82
0363407ee75c added object pool
cin
parents:
diff changeset
79 }
0363407ee75c added object pool
cin
parents:
diff changeset
80 }
0363407ee75c added object pool
cin
parents:
diff changeset
81
0363407ee75c added object pool
cin
parents:
diff changeset
82 #region IDisposable implementation
0363407ee75c added object pool
cin
parents:
diff changeset
83
0363407ee75c added object pool
cin
parents:
diff changeset
84 public void Dispose() {
0363407ee75c added object pool
cin
parents:
diff changeset
85 Dispose(true);
0363407ee75c added object pool
cin
parents:
diff changeset
86 GC.SuppressFinalize(this);
0363407ee75c added object pool
cin
parents:
diff changeset
87 }
0363407ee75c added object pool
cin
parents:
diff changeset
88
0363407ee75c added object pool
cin
parents:
diff changeset
89 #endregion
0363407ee75c added object pool
cin
parents:
diff changeset
90 }
0363407ee75c added object pool
cin
parents:
diff changeset
91 }
0363407ee75c added object pool
cin
parents:
diff changeset
92