annotate Implab/Components/ObjectPool.cs @ 196:40d7fed4a09e

fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
author cin
date Mon, 29 Aug 2016 23:15:51 +0300
parents 2dcdee4c0810
children 7c7e9ad6fe4a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
1 using Implab.Parallels;
240aa6994018 component model refactoring
cin
parents:
diff changeset
2 using System;
240aa6994018 component model refactoring
cin
parents:
diff changeset
3 using System.Threading;
240aa6994018 component model refactoring
cin
parents:
diff changeset
4
240aa6994018 component model refactoring
cin
parents:
diff changeset
5 namespace Implab.Components {
240aa6994018 component model refactoring
cin
parents:
diff changeset
6 /// <summary>
154
cin
parents: 152
diff changeset
7 /// The base class for creating object pools.
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
8 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
9 /// <remarks>
154
cin
parents: 152
diff changeset
10 /// <para>The objects pool is offers frequently requested objects to be reused, this gives
cin
parents: 152
diff changeset
11 /// a gool speed improvement for the 'heavy' objects. To avoid memory overhead the pool uses
cin
parents: 152
diff changeset
12 /// weak references allowing CG to do it's work. If there are no free objects in the pool
cin
parents: 152
diff changeset
13 /// they are created on demand. </para>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
14 /// <para>
154
cin
parents: 152
diff changeset
15 /// Implementors need to defined a <see cref="CreateInstance()"/> method
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
16 /// </para>
154
cin
parents: 152
diff changeset
17 /// <para>The instances of this class are thred-safe.</para>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
18 /// </remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
19 public abstract class ObjectPool<T> where T : class {
240aa6994018 component model refactoring
cin
parents:
diff changeset
20 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
240aa6994018 component model refactoring
cin
parents:
diff changeset
21 readonly int m_size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
22 int m_count = 0;
240aa6994018 component model refactoring
cin
parents:
diff changeset
23
240aa6994018 component model refactoring
cin
parents:
diff changeset
24 protected ObjectPool() : this(Environment.ProcessorCount+1) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
25
240aa6994018 component model refactoring
cin
parents:
diff changeset
26 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
27
240aa6994018 component model refactoring
cin
parents:
diff changeset
28 protected ObjectPool(int size) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
29 Safe.ArgumentInRange(size,1,size,"size");
240aa6994018 component model refactoring
cin
parents:
diff changeset
30
240aa6994018 component model refactoring
cin
parents:
diff changeset
31 m_size = size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
32 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
33
154
cin
parents: 152
diff changeset
34 /// <summary>
cin
parents: 152
diff changeset
35 /// Creates the instance if there are no free ones in the pool.
cin
parents: 152
diff changeset
36 /// </summary>
cin
parents: 152
diff changeset
37 /// <returns>The new instance.</returns>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
38 protected abstract T CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
39
154
cin
parents: 152
diff changeset
40 /// <summary>
cin
parents: 152
diff changeset
41 /// Cleanups the instance.
cin
parents: 152
diff changeset
42 /// </summary>
cin
parents: 152
diff changeset
43 /// <param name="instance">The instance to cleanup and prepare it for the next use.</param>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
44 protected virtual void CleanupInstance(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
45 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
46
154
cin
parents: 152
diff changeset
47 /// <summary>
cin
parents: 152
diff changeset
48 /// Allocate free instance from the pool or reates a new one.
cin
parents: 152
diff changeset
49 /// </summary>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
50 public T Allocate() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
51 WeakReference reference;
240aa6994018 component model refactoring
cin
parents:
diff changeset
52 while (m_queue.TryDequeue(out reference)) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
53 Interlocked.Decrement(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
54 object instance = reference.Target;
240aa6994018 component model refactoring
cin
parents:
diff changeset
55 if (instance == null)
240aa6994018 component model refactoring
cin
parents:
diff changeset
56 continue;
240aa6994018 component model refactoring
cin
parents:
diff changeset
57 return (T)instance;
240aa6994018 component model refactoring
cin
parents:
diff changeset
58 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
59 return CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
60 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
61
154
cin
parents: 152
diff changeset
62 /// <summary>
cin
parents: 152
diff changeset
63 /// Release the specified instance and returns it to the pool of free instances.
cin
parents: 152
diff changeset
64 /// </summary>
cin
parents: 152
diff changeset
65 /// <param name="instance">The instance to return to the pool.</param>
cin
parents: 152
diff changeset
66 /// <remarks>Before the instance is returned to the pool the <see cref="CleanupInstance(T)"/> is called.</remarks>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
67 public void Release(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
68 if (m_count < m_size && instance != null) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
69 Interlocked.Increment(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
70 CleanupInstance(instance);
240aa6994018 component model refactoring
cin
parents:
diff changeset
71 m_queue.Enqueue(new WeakReference(instance));
240aa6994018 component model refactoring
cin
parents:
diff changeset
72 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
73 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
74 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
75 }