annotate Implab/Components/DisposablePool.cs @ 190:1c2a16d071a7 v2

Слияние с ref20160224
author cin
date Fri, 22 Apr 2016 13:08:08 +0300
parents b933ec88446e
children c52691faaf21
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
1 using System;
240aa6994018 component model refactoring
cin
parents:
diff changeset
2 using Implab.Parallels;
240aa6994018 component model refactoring
cin
parents:
diff changeset
3 using System.Threading;
240aa6994018 component model refactoring
cin
parents:
diff changeset
4 using System.Diagnostics;
240aa6994018 component model refactoring
cin
parents:
diff changeset
5 using System.Diagnostics.CodeAnalysis;
240aa6994018 component model refactoring
cin
parents:
diff changeset
6
153
cin
parents: 152
diff changeset
7 namespace Implab.Components {
cin
parents: 152
diff changeset
8 /// <summary>
cin
parents: 152
diff changeset
9 /// The base class for implementing pools of disposable objects.
cin
parents: 152
diff changeset
10 /// </summary>
cin
parents: 152
diff changeset
11 /// <remarks>
cin
parents: 152
diff changeset
12 /// <para>This class maintains a set of pre-created objects and which are frequently allocated and released
cin
parents: 152
diff changeset
13 /// by clients. The pool maintains maximum number of unsued object, any object above this limit is disposed,
cin
parents: 152
diff changeset
14 /// if the pool is empty it will create new objects on demand.</para>
cin
parents: 152
diff changeset
15 /// <para>Instances of this class are thread-safe.</para>
cin
parents: 152
diff changeset
16 /// </remarks>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
17 public abstract class DisposablePool<T> : IDisposable {
240aa6994018 component model refactoring
cin
parents:
diff changeset
18 readonly int m_size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
19 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
240aa6994018 component model refactoring
cin
parents:
diff changeset
20
240aa6994018 component model refactoring
cin
parents:
diff changeset
21 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
240aa6994018 component model refactoring
cin
parents:
diff changeset
22 static readonly bool _isValueType = typeof(T).IsValueType;
240aa6994018 component model refactoring
cin
parents:
diff changeset
23
240aa6994018 component model refactoring
cin
parents:
diff changeset
24 bool m_disposed;
240aa6994018 component model refactoring
cin
parents:
diff changeset
25
240aa6994018 component model refactoring
cin
parents:
diff changeset
26 int m_count;
240aa6994018 component model refactoring
cin
parents:
diff changeset
27
240aa6994018 component model refactoring
cin
parents:
diff changeset
28 protected DisposablePool(int size) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
29 m_size = size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
30 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
31
240aa6994018 component model refactoring
cin
parents:
diff changeset
32 protected DisposablePool() : this(Environment.ProcessorCount+1) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
33 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
34
240aa6994018 component model refactoring
cin
parents:
diff changeset
35 public T Allocate() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
36 if (m_disposed)
240aa6994018 component model refactoring
cin
parents:
diff changeset
37 throw new ObjectDisposedException(ToString());
240aa6994018 component model refactoring
cin
parents:
diff changeset
38
240aa6994018 component model refactoring
cin
parents:
diff changeset
39 T instance;
240aa6994018 component model refactoring
cin
parents:
diff changeset
40 if (m_queue.TryDequeue(out instance)) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
41 Interlocked.Decrement(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
42 } else {
240aa6994018 component model refactoring
cin
parents:
diff changeset
43 instance = CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
44 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
240aa6994018 component model refactoring
cin
parents:
diff changeset
45 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
46 return instance;
240aa6994018 component model refactoring
cin
parents:
diff changeset
47 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
48
240aa6994018 component model refactoring
cin
parents:
diff changeset
49 protected abstract T CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
50
240aa6994018 component model refactoring
cin
parents:
diff changeset
51 protected virtual void CleanupInstance(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
52 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
53
240aa6994018 component model refactoring
cin
parents:
diff changeset
54 public void Release(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
55 if ( Object.Equals(instance,default(T)) && !_isValueType)
240aa6994018 component model refactoring
cin
parents:
diff changeset
56 return;
240aa6994018 component model refactoring
cin
parents:
diff changeset
57
240aa6994018 component model refactoring
cin
parents:
diff changeset
58 Thread.MemoryBarrier();
240aa6994018 component model refactoring
cin
parents:
diff changeset
59 if (m_count < m_size && !m_disposed) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
60 Interlocked.Increment(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
61
240aa6994018 component model refactoring
cin
parents:
diff changeset
62 CleanupInstance(instance);
240aa6994018 component model refactoring
cin
parents:
diff changeset
63
240aa6994018 component model refactoring
cin
parents:
diff changeset
64 m_queue.Enqueue(instance);
240aa6994018 component model refactoring
cin
parents:
diff changeset
65
240aa6994018 component model refactoring
cin
parents:
diff changeset
66 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
240aa6994018 component model refactoring
cin
parents:
diff changeset
67 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
240aa6994018 component model refactoring
cin
parents:
diff changeset
68 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
240aa6994018 component model refactoring
cin
parents:
diff changeset
69 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
240aa6994018 component model refactoring
cin
parents:
diff changeset
70 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
240aa6994018 component model refactoring
cin
parents:
diff changeset
71 ((IDisposable)instance).Dispose() ;
240aa6994018 component model refactoring
cin
parents:
diff changeset
72
240aa6994018 component model refactoring
cin
parents:
diff changeset
73 } else {
153
cin
parents: 152
diff changeset
74 var disposable = instance as IDisposable;
cin
parents: 152
diff changeset
75 if (disposable != null)
cin
parents: 152
diff changeset
76 disposable.Dispose();
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
77 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
78 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
79
240aa6994018 component model refactoring
cin
parents:
diff changeset
80 protected virtual void Dispose(bool disposing) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
81 if (disposing) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
82 m_disposed = true;
240aa6994018 component model refactoring
cin
parents:
diff changeset
83 T instance;
153
cin
parents: 152
diff changeset
84 while (m_queue.TryDequeue(out instance)) {
cin
parents: 152
diff changeset
85 var disposable = instance as IDisposable;
cin
parents: 152
diff changeset
86 if (disposable != null)
cin
parents: 152
diff changeset
87 disposable.Dispose();
cin
parents: 152
diff changeset
88 }
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
89 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
90 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
91
240aa6994018 component model refactoring
cin
parents:
diff changeset
92 #region IDisposable implementation
240aa6994018 component model refactoring
cin
parents:
diff changeset
93
240aa6994018 component model refactoring
cin
parents:
diff changeset
94 public void Dispose() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
95 Dispose(true);
240aa6994018 component model refactoring
cin
parents:
diff changeset
96 GC.SuppressFinalize(this);
240aa6994018 component model refactoring
cin
parents:
diff changeset
97 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
98
240aa6994018 component model refactoring
cin
parents:
diff changeset
99 #endregion
240aa6994018 component model refactoring
cin
parents:
diff changeset
100 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
101 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
102