annotate Implab/DisposablePool.cs @ 124:a336cb13c6a9 v2

major update, added Drain mathod to AsyncQueue class
author cin
date Thu, 15 Jan 2015 02:43:14 +0300
parents 2573b562e328
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
117
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
1 using System;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
2 using Implab.Parallels;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
3 using System.Threading;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
4 using System.Diagnostics;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
5 using System.Diagnostics.CodeAnalysis;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
6
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
7 namespace Implab {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
8 public abstract class DisposablePool<T> : IDisposable {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
9 readonly int m_size;
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 117
diff changeset
10 readonly AsyncQueue<T> m_queue = new AsyncQueue<T>();
117
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
11
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
13 static readonly bool _isValueType = typeof(T).IsValueType;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
14
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
15 bool m_disposed;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
16
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
17 int m_count;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
18
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
19 protected DisposablePool(int size) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
20 m_size = size;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
21 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
22
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
23 protected DisposablePool() : this(Environment.ProcessorCount+1) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
24 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
25
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
26 public T Allocate() {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
27 if (m_disposed)
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
28 throw new ObjectDisposedException(ToString());
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
29
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
30 T instance;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
31 if (m_queue.TryDequeue(out instance)) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
32 Interlocked.Decrement(ref m_count);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
33 } else {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
34 instance = CreateInstance();
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
35 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
36 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
37 return instance;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
38 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
39
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
40 protected abstract T CreateInstance();
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
41
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
42 protected virtual void CleanupInstance(T instance) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
43 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
44
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
45 public void Release(T instance) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
46 if ( Object.Equals(instance,default(T)) && !_isValueType)
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
47 return;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
48
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
49 Thread.MemoryBarrier();
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
50 if (m_count < m_size && !m_disposed) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
51 Interlocked.Increment(ref m_count);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
52
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
53 CleanupInstance(instance);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
54
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
55 m_queue.Enqueue(instance);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
56
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
57 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
58 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
59 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
60 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
61 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
62 ((IDisposable)instance).Dispose() ;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
63
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
64 } else {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
65 if (instance is IDisposable)
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
66 ((IDisposable)instance).Dispose();
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
67 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
68 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
69
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
70 protected virtual void Dispose(bool disposing) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
71 if (disposing) {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
72 m_disposed = true;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
73 T instance;
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
74 while (m_queue.TryDequeue(out instance))
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
75 if (instance is IDisposable)
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
76 ((IDisposable)instance).Dispose();
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
77 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
78 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
79
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
80 #region IDisposable implementation
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
81
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
82 public void Dispose() {
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
83 Dispose(true);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
84 GC.SuppressFinalize(this);
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
85 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
86
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
87 #endregion
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
88 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
89 }
8beee0d11de6 pool refactoring
cin
parents:
diff changeset
90