This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / TdsConnectionPool.cs
1 //
2 // Mono.Data.TdsClient.TdsConnectionPool.cs
3 //
4 // Author:
5 //   Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // Copyright (C) 2004 Novell, Inc.
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31 using Mono.Data.Tds.Protocol;
32 using System;
33 using System.Collections;
34 using System.Threading;
35
36 namespace Mono.Data.Tds.Protocol 
37 {
38         public class TdsConnectionPoolManager
39         {
40                 Hashtable pools = new Hashtable ();
41                 TdsVersion version;
42                 
43                 public TdsConnectionPoolManager (TdsVersion version)
44                 {
45                         this.version = version;
46                 }
47                 
48                 public TdsConnectionPool GetConnectionPool (string connectionString, TdsConnectionInfo info)
49                 {
50                         lock (pools)
51                         {
52                                 TdsConnectionPool pool = (TdsConnectionPool) pools [connectionString];
53                                 if (pool == null) {
54                                         pool = new TdsConnectionPool (this, info);
55                                         pools [connectionString] = pool;
56                                 }
57                                 return pool;
58                         }
59                 }
60                 
61                 public virtual ITds CreateConnection (TdsConnectionInfo info)
62                 {
63                         switch (version)
64                         {
65                                 case TdsVersion.tds42:
66                                         return new Tds42 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
67                                 case TdsVersion.tds50:
68                                         return new Tds50 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
69                                 case TdsVersion.tds70:
70                                         return new Tds70 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
71                                 case TdsVersion.tds80:
72                                         return new Tds80 (info.DataSource, info.Port, info.PacketSize, info.Timeout);
73                         }
74                         throw new NotSupportedException ();
75                 }
76         }
77         
78         public class TdsConnectionInfo
79         {
80                 public TdsConnectionInfo (string dataSource, int port, int packetSize, int timeout, int minSize, int maxSize)
81                 {
82                         DataSource = dataSource;
83                         Port = port;
84                         PacketSize = packetSize;
85                         Timeout = timeout;
86                         PoolMinSize = minSize;
87                         PoolMaxSize = maxSize;
88                 }
89                 
90                 public string DataSource;
91                 public int Port;
92                 public int PacketSize;
93                 public int Timeout;
94                 public int PoolMinSize;
95                 public int PoolMaxSize;
96         }
97         
98         public class TdsConnectionPool
99         {
100                 ArrayList list = new ArrayList ();
101                 TdsConnectionInfo info;
102                 bool initialized;
103                 int activeConnections = 0;
104                 TdsConnectionPoolManager manager;
105
106                 public TdsConnectionPool (TdsConnectionPoolManager manager, TdsConnectionInfo info)
107                 {
108                         this.info = info;
109                         this.manager = manager;
110                 }
111
112                 #region Methods
113
114                 public ITds GetConnection ()
115                 {
116                         ITds connection = null;
117                                 
118                         lock (list)
119                         {
120                                 if (!initialized) 
121                                 {
122                                         for (int n=0; n<info.PoolMinSize; n++)
123                                                 list.Add (CreateConnection ());
124                                         initialized = true;
125                                 }
126                                 
127                                 do {
128                                         if (list.Count > 0) 
129                                         {
130                                                 // There are available connections
131                                                 connection = (ITds) list [list.Count - 1];
132                                                 list.RemoveAt (list.Count - 1);
133                                                 if (!connection.Reset ()) {
134                                                         connection = null;
135                                                         continue;
136                                                 }
137                                         }
138
139                                         if (connection == null && activeConnections < info.PoolMaxSize)
140                                         {
141                                                 // No connections available, but the connection limit
142                                                 // has not been reached yet, so a new one can be created
143                                                 connection = CreateConnection();
144                                         }
145
146                                         // No available connections in the pool
147                                         // Wait for somewone to release one.
148                                         if (connection == null)
149                                         {
150                                                 Monitor.Wait (list);
151                                         }
152                                 } 
153                                 while (connection == null);
154                         }
155
156                         return connection;
157                 }
158
159                 public void ReleaseConnection (ITds tds)
160                 {
161                         lock (list)
162                         {
163                                 list.Add (tds);
164                                 Monitor.Pulse (list);
165                         }
166                 }
167                 
168                 ITds CreateConnection ()
169                 {
170                         activeConnections++;
171                         return manager.CreateConnection (info);
172                 }
173                 
174                 #endregion // Methods
175         }
176 }