You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
#if MYSQL_6_9
// Copyright ?2004, 2013, Oracle and/or its affiliates. All rights reserved.
//
// MySQL Connector/NET is licensed under the terms of the GPLv2
// <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
// MySQL Connectors. There are special exceptions to the terms and
// conditions of the GPLv2 as it is applied to this software, see the
// FLOSS License Exception
// <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
using System; using System.Collections; using System.Diagnostics; using System.Collections.Generic; using System.Threading; using Externals.MySql.Data.MySqlClient.Properties;
namespace Externals.MySql.Data.MySqlClient { /// <summary>
/// Summary description for MySqlPoolManager.
/// </summary>
internal class MySqlPoolManager { private static Dictionary<string, MySqlPool> pools = new Dictionary<string, MySqlPool>(); private static List<MySqlPool> clearingPools = new List<MySqlPool>();
// Timeout in seconds, after which an unused (idle) connection
// should be closed.
static internal int maxConnectionIdleTime = 180;
static MySqlPoolManager() { AppDomain.CurrentDomain.ProcessExit += new EventHandler(EnsureClearingPools); AppDomain.CurrentDomain.DomainUnload += new EventHandler(EnsureClearingPools); }
private static void EnsureClearingPools( object sender, EventArgs e ) { MySqlPoolManager.ClearAllPools(); }
// we add a small amount to the due time to let the cleanup detect
//expired connections in the first cleanup.
private static Timer timer = new Timer(new TimerCallback(CleanIdleConnections), null, (maxConnectionIdleTime * 1000) + 8000, maxConnectionIdleTime * 1000); private static string GetKey(MySqlConnectionStringBuilder settings) { string key = ""; lock (settings) { key = settings.ConnectionString; } if (settings.IntegratedSecurity && !settings.ConnectionReset) { try { // Append SID to the connection string to generate a key
// With Integrated security different Windows users with the same
// connection string may be mapped to different MySQL accounts.
System.Security.Principal.WindowsIdentity id = System.Security.Principal.WindowsIdentity.GetCurrent();
key += ";" + id.User; } catch (System.Security.SecurityException ex) { // Documentation for WindowsIdentity.GetCurrent() states
// SecurityException can be thrown. In this case the
// connection can only be pooled if reset is done.
throw new MySqlException(Resources.NoWindowsIdentity, ex); } } return key; } public static MySqlPool GetPool(MySqlConnectionStringBuilder settings) { string text = GetKey(settings);
lock (pools) { MySqlPool pool; pools.TryGetValue(text, out pool);
if (pool == null) { pool = new MySqlPool(settings); pools.Add(text, pool); } else pool.Settings = settings;
return pool; } }
public static void RemoveConnection(Driver driver) { Debug.Assert(driver != null);
MySqlPool pool = driver.Pool; if (pool == null) return;
pool.RemoveConnection(driver); }
public static void ReleaseConnection(Driver driver) { Debug.Assert(driver != null);
MySqlPool pool = driver.Pool; if (pool == null) return;
pool.ReleaseConnection(driver); }
public static void ClearPool(MySqlConnectionStringBuilder settings) { Debug.Assert(settings != null); string text; try { text = GetKey(settings); } catch (MySqlException) { // Cannot retrieve windows identity for IntegratedSecurity=true
// This can be ignored.
return; } ClearPoolByText(text); }
private static void ClearPoolByText(string key) { lock (pools) { // if pools doesn't have it, then this pool must already have been cleared
if (!pools.ContainsKey(key)) return;
// add the pool to our list of pools being cleared
MySqlPool pool = (pools[key] as MySqlPool); clearingPools.Add(pool);
// now tell the pool to clear itself
pool.Clear();
// and then remove the pool from the active pools list
pools.Remove(key); } }
public static void ClearAllPools() { lock (pools) { // Create separate keys list.
List<string> keys = new List<string>(pools.Count);
foreach (string key in pools.Keys) keys.Add(key);
// Remove all pools by key.
foreach (string key in keys) ClearPoolByText(key); } }
public static void RemoveClearedPool(MySqlPool pool) { Debug.Assert(clearingPools.Contains(pool)); clearingPools.Remove(pool); }
/// <summary>
/// Remove drivers that have been idle for too long.
/// </summary>
public static void CleanIdleConnections(object obj) { List<Driver> oldDrivers = new List<Driver>(); lock (pools) { foreach (string key in pools.Keys) { MySqlPool pool = (pools[key] as MySqlPool); oldDrivers.AddRange(pool.RemoveOldIdleConnections()); } } foreach (Driver driver in oldDrivers) { driver.Close(); } } } }
#endif
|