2 // Mono.Data.TdsClient.TdsConnectionPool.cs
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // Copyright (C) 2004 Novell, Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using Mono.Data.Tds.Protocol;
33 using System.Collections;
34 using System.Threading;
36 namespace Mono.Data.Tds.Protocol
38 public class TdsConnectionPoolManager
40 Hashtable pools = new Hashtable ();
43 public TdsConnectionPoolManager (TdsVersion version)
45 this.version = version;
48 public TdsConnectionPool GetConnectionPool (string connectionString, TdsConnectionInfo info)
52 TdsConnectionPool pool = (TdsConnectionPool) pools [connectionString];
54 pool = new TdsConnectionPool (this, info);
55 pools [connectionString] = pool;
61 public Hashtable GetConnectionPool ()
69 public virtual ITds CreateConnection (TdsConnectionInfo info)
73 case TdsVersion.tds42:
74 return new Tds42 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
75 case TdsVersion.tds50:
76 return new Tds50 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
77 case TdsVersion.tds70:
78 return new Tds70 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
79 case TdsVersion.tds80:
80 return new Tds80 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
82 throw new NotSupportedException ();
86 public class TdsConnectionInfo
88 public TdsConnectionInfo (string dataSource, int port, int packetSize, int timeout, int minSize, int maxSize)
90 DataSource = dataSource;
92 PacketSize = packetSize;
94 PoolMinSize = minSize;
95 PoolMaxSize = maxSize;
98 public string DataSource;
100 public int PacketSize;
102 public int PoolMinSize;
103 public int PoolMaxSize;
106 public class TdsConnectionPool
108 ArrayList list = new ArrayList ();
109 TdsConnectionInfo info;
111 static bool pooling = false;
112 int activeConnections = 0;
113 TdsConnectionPoolManager manager;
115 public TdsConnectionPool (TdsConnectionPoolManager manager, TdsConnectionInfo info)
118 this.manager = manager;
121 public static bool Pooling {
122 get { return pooling; }
123 set { pooling = value; }
128 public ITds GetConnection ()
130 ITds connection = null;
135 for (int n = 0; n < info.PoolMinSize; n++)
136 list.Add (CreateConnection ());
142 // There are available connections
143 connection = (ITds) list [list.Count - 1];
144 list.RemoveAt (list.Count - 1);
145 if (!connection.Reset ()) {
147 connection.Disconnect ();
154 if (connection == null && activeConnections < info.PoolMaxSize)
156 // No connections available, but the connection limit
157 // has not been reached yet, so a new one can be created
158 connection = CreateConnection();
161 // No available connections in the pool
162 // Wait for somewone to release one.
163 if (connection == null)
168 while (connection == null);
174 public void ReleaseConnection (ITds tds)
179 Monitor.Pulse (list);
184 public void ReleaseConnection (ref ITds tds)
188 if (pooling == false) {
195 Monitor.Pulse (list);
200 public void ResetConnectionPool ()
204 ITds connection = null;
205 while (list.Count > 0) {
206 // There are available connections
207 connection = (ITds) list [list.Count - 1];
208 list.RemoveAt (list.Count - 1);
209 if (!connection.Reset ()) {
211 connection.Disconnect ();
219 public void ResetConnectionPool (ITds connection)
223 if (list.Count > 0) {
224 // There are available connections
225 int index = list.IndexOf (connection);
227 list.RemoveAt (index);
228 if (!connection.Reset ()) {
230 connection.Disconnect ();
240 ITds CreateConnection ()
243 return manager.CreateConnection (info);
246 #endregion // Methods