I haven't checked it yet, can i send to you a coipy of the=20 CVS sources if they didn't work well i will review your patch, ok ??
Thanks for sources, but there are a few broblems :-(
First problem is that you sent us sources of the provider v2.0 and we use
1.7.1. But this is not a big problem.
Next problem is that i still seeing bugs that we fixed in our version wich i
sent to you:
1) We think it will be better to add locking in Count property:
public int Count
{
get
{
lock (this.unlocked.SyncRoot)
{
return this.unlocked.Count +
this.locked.Count;
}
}
}
2) We assured that moving from locked list to unlocked and vice-verca must be
atomicity operation. So, we propose to add the special method for this:
#region Types
private enum MoveType {LockedToUnlocked, UnlockedToLocked}
#endregion
private void MoveConnection(FbConnectionInternal connection,
MoveType moveType)
{
if (null == connection)
return;
lock (this.unlocked.SyncRoot)
{
switch (moveType)
{
case MoveType.LockedToUnlocked:
this.locked.Remove(connection);
this.unlocked.Add(connection);
break;
case MoveType.UnlockedToLocked:
this.unlocked.Remove(connection);
this.locked.Add(connection);
break;
}
}
}
and replace old code by calling new method:
a) in CheckIn:
from
this.locked.Remove(connection);
this.unlocked.Add(connection);
to
MoveConnection(connection, MoveType.LockedToUnlocked);
b) in GetConnection():
from
if (result != null)
{
this.unlocked.Remove(result);
this.locked.Add(result);
to
if (result != null)
MoveConnection(result,
MoveType.UnlockedToLocked);
3) It will be more clear if you will move locking of GetConnection calls from
CheckOut inside of GetConnection. So, we will have such code:
for CheckOut:
public FbConnectionInternal CheckOut()
{
FbConnectionInternal newConnection = null;
lock (this.syncObject)
{
// 1. Try to get a connection from the unlocked
connection list
newConnection = this.GetConnection();
if (newConnection != null)
return newConnection;
// 2. Check if we have reached the max number
of allowed connections
this.CheckMaxPoolSize();
// 3. Try to get a connection from the unlocked
connection list
newConnection = this.GetConnection();
if (newConnection != null)
return newConnection;
for GetConnection:
private FbConnectionInternal GetConnection()
{
FbConnectionInternal result = null;
long check = -1;
lock (this.unlocked.SyncRoot)
{
FbConnectionInternal[] connections =
(FbConnectionInternal[]) this.unlocked.ToArray(typeof(FbConnectionInternal));
for (int i = connections.Length - 1; i >= 0; i--)
{
if (connections[i].Verify())
{
if (this.lifeTime != 0)
{
long now =
DateTime.Now.Ticks;
long expire =
connections[i].Created + this.lifeTime;
if (now >= expire)
{
if
(this.CheckMinPoolSize())
{
this.unlocked.Remove(connections[i]);
this.Expire(connections[i]);
}
}
else
{
if (expire >
check)
{
check =
expire;
result
= connections[i];
}
}
}
else
{
result = connections[i];
break;
}
}
else
{
this.unlocked.Remove(connections[i]);
this.Expire(connections[i]);
}
}
4) Aslso we assured that in MaxPoolSize we should not only check for this.Count
>= this.options.MaxPoolSize, but also we should check if existing locked
connection was moved to unlocked:
public bool HasUnlocked
{
get { return this.unlocked.Count > 0; }
}
private bool CheckMinPoolSize()
{
if (this.options.MinPoolSize > 0 && this.Count <=
this.options.MinPoolSize)
{
return false;
}
else
{
return true;
}
}
private void CheckMaxPoolSize()
{
if (this.options.MaxPoolSize > 0 && this.Count >=
this.options.MaxPoolSize)
{
long timeout = this.options.ConnectionTimeout *
TimeSpan.TicksPerSecond;
long start = DateTime.Now.Ticks;
/*
Loop brakes without errors in next situations:
1. connection was returned from locked to unlocked by calling CheckIn in other thread (HasUnlocked = true)
2. connection was moved from locked to unlocked (by Checkin) and then cleaned (removed from unlocked by Cleanup)
*/
while (true)
{
if (this.Count >= this.options.MaxPoolSize
&& this.HasUnlocked == false)
{
if ((DateTime.Now.Ticks - start)
> timeout)
throw new
SystemException("Timeout exceeded.");
Thread.Sleep(100);
}
else
break;
}
}
}
All this changes you can find in version wich we sent to you.
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Firebird-net-provider mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider
