annotate Implab/Components/DisposablePool.cs @ 209:a867536c68fc v2

Bound promise to CancellationToken Added new states to ExecutionSate enum. Added Safe.Guard() method to handle cleanup of the result of the promise
author cin
date Wed, 16 Nov 2016 03:06: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