Modified:
branches/5.2/CHANGES
branches/5.2/MySql.Data/Provider/MySql.Data.CF.csproj
branches/5.2/MySql.Data/Provider/MySql.Data.csproj
branches/5.2/MySql.Data/Provider/Source/MySqlPool.cs
branches/5.2/MySql.Data/Provider/Source/MySqlPoolManager.cs
Log:
Removed some unnecessary locking from the pool manager and also reworked the pooling code
to not use a semaphore (bug #34001)
Modified: branches/5.2/CHANGES
===================================================================
--- branches/5.2/CHANGES 2008-05-07 13:44:05 UTC (rev 1281)
+++ branches/5.2/CHANGES 2008-05-07 13:47:00 UTC (rev 1282)
@@ -22,6 +22,9 @@
- The procedure parameters schema collection has been altered to match what is coming
with MySQL 6.0. Some fields have been removed and others combined. Please review
your application for incompatibilities.
+- Removed some unnecessary locking from the pool manager and also reworked the pooling
+ code to not use a semaphore (bug #34001)
+
Version 5.2.1 - 2/27/2008
- Tons of fixes in providers. The actually work now. :)
Modified: branches/5.2/MySql.Data/Provider/MySql.Data.CF.csproj
===================================================================
--- branches/5.2/MySql.Data/Provider/MySql.Data.CF.csproj 2008-05-07 13:44:05 UTC (rev
1281)
+++ branches/5.2/MySql.Data/Provider/MySql.Data.CF.csproj 2008-05-07 13:47:00 UTC (rev
1282)
@@ -63,7 +63,6 @@
<Compile Include="Source\base\DbConnectionStringBuilder.cs" />
<Compile Include="Source\base\DbException.cs" />
<Compile Include="Source\cf\BufferedStream.cs" />
- <Compile Include="Source\cf\Semaphore.cs" />
<Compile Include="Source\cf\WinCE.cs" />
<Compile Include="Source\CharSetMap.cs" />
<Compile Include="Source\command.cs">
Modified: branches/5.2/MySql.Data/Provider/MySql.Data.csproj
===================================================================
--- branches/5.2/MySql.Data/Provider/MySql.Data.csproj 2008-05-07 13:44:05 UTC (rev 1281)
+++ branches/5.2/MySql.Data/Provider/MySql.Data.csproj 2008-05-07 13:47:00 UTC (rev 1282)
@@ -221,7 +221,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\Resources.Designer.cs" />
- <Compile Include="Source\cf\Semaphore.cs" />
<Compile Include="Source\common\Cache.cs" />
<Compile Include="Source\common\SqlTokenizer.cs" />
<Compile Include="Source\BulkLoader.cs" />
Modified: branches/5.2/MySql.Data/Provider/Source/MySqlPool.cs
===================================================================
--- branches/5.2/MySql.Data/Provider/Source/MySqlPool.cs 2008-05-07 13:44:05 UTC (rev
1281)
+++ branches/5.2/MySql.Data/Provider/Source/MySqlPool.cs 2008-05-07 13:47:00 UTC (rev
1282)
@@ -20,12 +20,9 @@
using System;
using System.Collections;
-using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
-#if CF
-using MySql.Data.Common;
-#endif
+using System.Threading;
namespace MySql.Data.MySqlClient
{
@@ -46,13 +43,18 @@
private uint maxSize;
private ProcedureCache procedureCache;
private Object lockObject;
- private Semaphore poolGate;
private bool beingCleared;
+ private int available;
+ private AutoResetEvent autoEvent;
public MySqlPool(MySqlConnectionStringBuilder settings)
{
minSize = settings.MinimumPoolSize;
maxSize = settings.MaximumPoolSize;
+
+ available = (int)maxSize;
+ autoEvent = new AutoResetEvent(false);
+
if (minSize > maxSize)
minSize = maxSize;
this.settings = settings;
@@ -69,7 +71,6 @@
idlePool.Enqueue(CreateNewPooledConnection());
procedureCache = new ProcedureCache((int)settings.ProcedureCacheSize);
- poolGate = new Semaphore((int)maxSize, (int)maxSize);
// we don't really need to create this but it makes the code a bit cleaner
lockObject = new Object();
@@ -165,6 +166,8 @@
/// </summary>
private Driver CreateNewPooledConnection()
{
+ Debug.Assert((maxSize - NumConnections) > 0, "Pool out of sync.");
+
Driver driver = Driver.Create(settings);
driver.Pool = this;
return driver;
@@ -185,9 +188,8 @@
else
idlePool.Enqueue(driver);
- // we now either have a connection available or have room to make
- // one so we release one slot in our semaphore
- poolGate.Release();
+ Interlocked.Increment(ref available);
+ autoEvent.Set();
}
}
@@ -205,7 +207,8 @@
if (inUsePool.Contains(driver))
{
inUsePool.Remove(driver);
- poolGate.Release();
+ Interlocked.Increment(ref available);
+ autoEvent.Set();
}
// if we are being cleared and we are out of connections then have
@@ -215,32 +218,45 @@
}
}
+ private Driver TryToGetDriver()
+ {
+ int count = Interlocked.Decrement(ref available);
+ if (count < 0)
+ {
+ Interlocked.Increment(ref available);
+ return null;
+ }
+ try
+ {
+ Driver driver = GetPooledConnection();
+ return driver;
+ }
+ catch (Exception ex)
+ {
+ if (settings.Logging)
+ Logger.LogException(ex);
+ Interlocked.Increment(ref available);
+ throw;
+ }
+ }
+
public Driver GetConnection()
{
- int ticks = (int)settings.ConnectionTimeout * 1000;
+ int fullTimeOut = (int)settings.ConnectionTimeout * 1000;
+ int timeOut = fullTimeOut;
- // wait till we are allowed in
- bool allowed = poolGate.WaitOne(ticks, false);
- if (! allowed)
- throw new MySqlException(Resources.TimeoutGettingConnection);
+ DateTime start = DateTime.Now;
- // if we get here, then it means that we either have an idle connection
- // or room to make a new connection
- lock (lockObject)
+ while (timeOut > 0)
{
- try
- {
- Driver d = GetPooledConnection();
- return d;
- }
- catch (Exception ex)
- {
- if (settings.Logging)
- Logger.LogException(ex);
- poolGate.Release();
- throw;
- }
+ Driver driver = TryToGetDriver();
+ if (driver != null) return driver;
+
+ // We have no tickets right now, lets wait for one.
+ if (!autoEvent.WaitOne(timeOut, false)) break;
+ timeOut = fullTimeOut -
(int)DateTime.Now.Subtract(start).TotalMilliseconds;
}
+ throw new MySqlException(Resources.TimeoutGettingConnection);
}
/// <summary>
Modified: branches/5.2/MySql.Data/Provider/Source/MySqlPoolManager.cs
===================================================================
--- branches/5.2/MySql.Data/Provider/Source/MySqlPoolManager.cs 2008-05-07 13:44:05 UTC
(rev 1281)
+++ branches/5.2/MySql.Data/Provider/Source/MySqlPoolManager.cs 2008-05-07 13:47:00 UTC
(rev 1282)
@@ -66,10 +66,7 @@
MySqlPool pool = driver.Pool;
if (pool == null) return;
- lock (pools.SyncRoot)
- {
- pool.RemoveConnection(driver);
- }
+ pool.RemoveConnection(driver);
}
public static void ReleaseConnection(Driver driver)
@@ -77,10 +74,7 @@
MySqlPool pool = driver.Pool;
if (pool == null) return;
- lock (pools.SyncRoot)
- {
- pool.ReleaseConnection(driver);
- }
+ pool.ReleaseConnection(driver);
}
public static void ClearPool(MySqlConnectionStringBuilder settings)
| Thread |
|---|
| • Connector/NET commit: r1282 - in branches/5.2: . MySql.Data/Provider MySql.Data/Provider/Source | rburnett | 7 May |