Fixing an issue with output parameters that are of type IntPtr
[castle.git] / InversionOfControl / Castle.MicroKernel / Lifestyle / Pool / DefaultPool.cs
blob229ef9e7a2addc6d11408effce142bf28b19d274
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MicroKernel.Lifestyle.Pool
17 using System;
18 using System.Threading;
19 using System.Collections;
21 using Castle.Core;
23 [Serializable]
24 public class DefaultPool : IPool, IDisposable
26 private readonly Stack available = Stack.Synchronized(new Stack());
27 private readonly IList inUse = ArrayList.Synchronized(new ArrayList());
28 private readonly int initialsize;
29 private readonly int maxsize;
30 private readonly ReaderWriterLock rwlock;
31 private readonly IComponentActivator componentActivator;
33 public DefaultPool(int initialsize, int maxsize, IComponentActivator componentActivator)
35 this.initialsize = initialsize;
36 this.maxsize = maxsize;
37 this.componentActivator = componentActivator;
39 this.rwlock = new ReaderWriterLock();
41 // Thread thread = new Thread(new ThreadStart(InitPool));
42 // thread.Start();
43 InitPool();
46 #region IPool Members
48 public virtual object Request(CreationContext context)
50 rwlock.AcquireWriterLock(-1);
52 object instance = null;
54 try
57 if (available.Count != 0)
59 instance = available.Pop();
61 if (instance == null)
63 throw new PoolException("Invalid instance on the pool stack");
66 else
68 instance = componentActivator.Create(context);
70 if (instance == null)
72 throw new PoolException("Activator didn't return a valid instance");
76 inUse.Add(instance);
78 finally
80 rwlock.ReleaseWriterLock();
83 return instance;
86 public virtual void Release(object instance)
88 rwlock.AcquireWriterLock(-1);
90 try
92 if (!inUse.Contains(instance))
94 throw new PoolException("Trying to release a component that does not belong to this pool");
97 inUse.Remove(instance);
99 if (available.Count < maxsize)
101 if (instance is IRecyclable)
103 (instance as IRecyclable).Recycle();
106 available.Push(instance);
108 else
110 // Pool is full
111 componentActivator.Destroy(instance);
114 finally
116 rwlock.ReleaseWriterLock();
120 #endregion
122 #region IDisposable Members
124 public virtual void Dispose()
126 // Release all components
128 foreach(object instance in available)
130 componentActivator.Destroy(instance);
134 #endregion
136 /// <summary>
137 /// Initializes the pool to a initial size by requesting
138 /// n components and then releasing them.
139 /// </summary>
140 private void InitPool()
142 ArrayList tempInstance = new ArrayList();
144 for(int i=0; i < initialsize; i++)
146 tempInstance.Add(Request(CreationContext.Empty));
149 for(int i=0; i < initialsize; i++)
151 Release(tempInstance[i]);