##// END OF EJS Templates
fixed object pool
cin -
r83:397fe8db0806 v2
parent child
Show More
@@ -1,85 +1,92
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3 using System.Threading;
3 using System.Threading;
4
4
5 namespace Implab {
5 namespace Implab {
6 public class ObjectPool<T> : IDisposable {
6 public class ObjectPool<T> : IDisposable {
7 readonly Func<T> m_factory;
7 readonly Func<T> m_factory;
8 readonly Action<T> m_cleanup;
8 readonly Action<T> m_cleanup;
9 readonly int m_size;
9 readonly int m_size;
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
11
11
12 volatile bool m_disposed;
12 bool m_disposed;
13
13
14 volatile int m_count;
14 int m_count;
15
15
16 public ObjectPool(Func<T> factory, Action<T> cleanup, int size) {
16 public ObjectPool(Func<T> factory, Action<T> cleanup, int size) {
17 Safe.ArgumentNotNull(factory, "factory");
17 Safe.ArgumentNotNull(factory, "factory");
18 Safe.ArgumentInRange(size, 1, size, "size");
18 Safe.ArgumentInRange(size, 1, size, "size");
19
19
20 m_factory = factory;
20 m_factory = factory;
21 m_cleanup = cleanup;
21 m_cleanup = cleanup;
22 m_size = size;
22 m_size = size;
23 }
23 }
24
24
25 public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
25 public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
26 }
26 }
27
27
28 public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) {
28 public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) {
29 }
29 }
30
30
31 public ObjectPoolWrapper<T> Allocate() {
31 public ObjectPoolWrapper<T> AllocateAuto() {
32
33 return new ObjectPoolWrapper<T>(Allocate(), this);
34 }
35
36 public T Allocate() {
32 if (m_disposed)
37 if (m_disposed)
33 throw new ObjectDisposedException(this.ToString());
38 throw new ObjectDisposedException(this.ToString());
34
39
35 T instance;
40 T instance;
36 if (m_queue.TryDequeue(out instance)) {
41 if (m_queue.TryDequeue(out instance)) {
37 Interlocked.Decrement(ref m_count);
42 Interlocked.Decrement(ref m_count);
38 return instance;
39 } else {
43 } else {
40 instance = m_factory();
44 instance = m_factory();
41 }
45 }
42 return new ObjectPoolWrapper<T>(instance, this);
46 return instance;
43 }
47 }
44
48
45 public void Release(T instance) {
49 public void Release(T instance) {
50 Thread.MemoryBarrier();
46 if (m_count < m_size && !m_disposed) {
51 if (m_count < m_size && !m_disposed) {
47 Interlocked.Increment(ref m_count);
52 Interlocked.Increment(ref m_count);
48
53
49 if (m_cleanup != null)
54 if (m_cleanup != null)
50 m_cleanup(instance);
55 m_cleanup(instance);
51
56
52 m_queue.Enqueue(instance);
57 m_queue.Enqueue(instance);
53
58
54 // ΠΏΠΎΠΊΠ° элСмСнт возвращался Π² кСш, Π±Ρ‹Π»Π° Π½Π°Ρ‡Π°Ρ‚Π° опСрация освобоТдСния всСго кСша
59 // ΠΏΠΎΠΊΠ° элСмСнт возвращался Π² кСш, Π±Ρ‹Π»Π° Π½Π°Ρ‡Π°Ρ‚Π° опСрация освобоТдСния всСго кСша
55 // ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΆΠ΅ Π·Π°ΠΊΠΎΠ½Ρ†Π΅Π½Π°, Π² Ρ‚Π°ΠΊΠΎΠΌ случаС слСдуСт ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈ
60 // ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΆΠ΅ Π·Π°ΠΊΠΎΠ½Ρ†Π΅Π½Π°, Π² Ρ‚Π°ΠΊΠΎΠΌ случаС слСдуСт ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΈ
56 // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ. Если опСрация освобоТдСния кСша Π΅Ρ‰Π΅ Π½Π΅ Π·Π°Π²Ρ€Π΅ΡˆΠΈΠ»Π°ΡΡŒ, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚
61 // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ. Если опСрация освобоТдСния кСша Π΅Ρ‰Π΅ Π½Π΅ Π·Π°Π²Ρ€Π΅ΡˆΠΈΠ»Π°ΡΡŒ, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚
57 // ΠΈΠ·ΡŠΡΡ‚ ΠΈ освобоТдСн ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ элСмСн, Ρ‡Ρ‚ΠΎ Π½Π΅ повлияСт Π½Π° Ρ…ΠΎΠ΄ всСго процСсса.
62 // ΠΈΠ·ΡŠΡΡ‚ ΠΈ освобоТдСн ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ элСмСн, Ρ‡Ρ‚ΠΎ Π½Π΅ повлияСт Π½Π° Ρ…ΠΎΠ΄ всСго процСсса.
58 if (m_disposed && m_queue.TryDequeue(out instance))
63 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
59 Safe.Dispose(instance);
64 ((IDisposable)instance).Dispose() ;
60
65
61 } else {
66 } else {
62 Safe.Dispose(instance);
67 if (instance is IDisposable)
68 ((IDisposable)instance).Dispose();
63 }
69 }
64 }
70 }
65
71
66 protected virtual void Dispose(bool disposing) {
72 protected virtual void Dispose(bool disposing) {
67 if (disposing) {
73 if (disposing) {
68 m_disposed = true;
74 m_disposed = true;
69 T instance;
75 T instance;
70 while (m_queue.TryDequeue(out instance))
76 while (m_queue.TryDequeue(out instance))
71 Safe.Dispose(instance);
77 if (instance is IDisposable)
78 ((IDisposable)instance).Dispose();
72 }
79 }
73 }
80 }
74
81
75 #region IDisposable implementation
82 #region IDisposable implementation
76
83
77 public void Dispose() {
84 public void Dispose() {
78 Dispose(true);
85 Dispose(true);
79 GC.SuppressFinalize(this);
86 GC.SuppressFinalize(this);
80 }
87 }
81
88
82 #endregion
89 #endregion
83 }
90 }
84 }
91 }
85
92
General Comments 0
You need to be logged in to leave comments. Login now