File: MySqlPool.cs

package info (click to toggle)
mono 2.6.7-5.1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 327,344 kB
  • ctags: 413,649
  • sloc: cs: 2,471,883; xml: 1,768,594; ansic: 350,665; sh: 13,644; makefile: 8,640; perl: 1,784; asm: 717; cpp: 209; python: 146; sql: 81; sed: 16
file content (135 lines) | stat: -rw-r--r-- 3,588 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System;
using ByteFX.Data.Common;
using System.Collections;

namespace ByteFX.Data.MySqlClient
{
	/// <summary>
	/// Summary description for MySqlPool.
	/// </summary>
	internal sealed class MySqlPool
	{
		private ArrayList				inUsePool;
		private ArrayList				idlePool;
		private MySqlConnectionString	settings;
		private int						minSize;
		private int						maxSize;

		public MySqlPool(MySqlConnectionString settings)
		{
			minSize = settings.MinPoolSize;
			maxSize = settings.MaxPoolSize;
			this.settings = settings;
			inUsePool =new ArrayList();
			idlePool = new ArrayList( settings.MinPoolSize );

			// prepopulate the idle pool to minSize
			for (int i=0; i < minSize; i++) 
				CreateNewPooledConnection();
		}

		private void CheckOutConnection(MySqlInternalConnection conn) 
		{
		}

		private MySqlInternalConnection GetPooledConnection()
		{
			MySqlInternalConnection conn = null;

			// if there are no idle connections and the in use pool is full
			// then return null to indicate that we cannot provide a connection
			// at this time.
			if (idlePool.Count == 0 && inUsePool.Count == maxSize) return null;

			lock (idlePool.SyncRoot) 
			{
				for (int i=idlePool.Count-1; i >=0; i--)
				{
					conn = (idlePool[i] as MySqlInternalConnection);
					if (conn.IsAlive()) 
					{
						lock (inUsePool) 
						{
							inUsePool.Add( conn );
						}
						idlePool.RemoveAt( i );
						return conn;
					}
					else 
					{
						conn.Close();
						idlePool.RemoveAt(i);
						conn = null;
					}
				}
			}

			// if we couldn't get a pooled connection and there is still room
			// make a new one
			if (conn == null && (idlePool.Count+inUsePool.Count) < maxSize)
			{
				conn = CreateNewPooledConnection();
				if (conn == null) return null;

				lock (idlePool.SyncRoot)
					lock (inUsePool.SyncRoot) 
					{
						idlePool.Remove( conn );
						inUsePool.Add( conn );
					}
			}

			return conn;
		}

		private MySqlInternalConnection CreateNewPooledConnection()
		{
			lock(idlePool.SyncRoot) 
				lock (inUsePool.SyncRoot)
				{
					// first we check if we are allowed to create another
					if ((inUsePool.Count + idlePool.Count) == maxSize) return null;

					MySqlInternalConnection conn = new MySqlInternalConnection( settings );
					conn.Open();
					idlePool.Add( conn );
					return conn;
				}
		}

		public void ReleaseConnection( MySqlInternalConnection connection )
		{
			lock (idlePool.SyncRoot)
				lock (inUsePool.SyncRoot) 
				{
					inUsePool.Remove( connection );
					if (connection.Settings.ConnectionLifetime != 0 && connection.IsTooOld())
						connection.Close();
					else
						idlePool.Add( connection );
				}
		}

		public MySqlInternalConnection GetConnection() 
		{
			MySqlInternalConnection conn = null;

			int start = Environment.TickCount;
			int ticks = settings.ConnectionTimeout * 1000;

			// wait timeOut seconds at most to get a connection
			while (conn == null && (Environment.TickCount - start) < ticks)
				conn = GetPooledConnection();
					 
			// if pool size is at maximum, then we must have reached our timeout so we simply
			// throw our exception
			if (conn == null)
				throw new MySqlException("error connecting: Timeout expired.  The timeout period elapsed " + 
					"prior to obtaining a connection from the pool.  This may have occurred because all " +
					"pooled connections were in use and max pool size was reached.");

			return conn;
		}

	}
}