mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-15 08:01:33 +00:00
Attempted deadlock fix
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@38606 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9282a5134d
commit
c47c323a7f
2 changed files with 62 additions and 5 deletions
|
@ -1,3 +1,9 @@
|
|||
2015-06-09 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* SQLClient.m: Fix reace condition spotted by Wolfgang and change
|
||||
purge operation to avoid disconnecting clients while the class lock
|
||||
is locked.
|
||||
|
||||
2015-05-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* SQLClient.h: Add pool purge control method.
|
||||
|
|
61
SQLClient.m
61
SQLClient.m
|
@ -903,10 +903,15 @@ static int poolConnections = 0;
|
|||
+ (void) purgeConnections: (NSDate*)since
|
||||
{
|
||||
NSHashEnumerator e;
|
||||
NSMutableArray *a = nil;
|
||||
SQLClient *o;
|
||||
unsigned int connectionCount = 0;
|
||||
NSTimeInterval t = [since timeIntervalSinceReferenceDate];
|
||||
NSTimeInterval t;
|
||||
|
||||
t = (nil == since) ? 0.0 : [since timeIntervalSinceReferenceDate];
|
||||
|
||||
/* Find clients we may want to disconnect.
|
||||
*/
|
||||
[clientsLock lock];
|
||||
e = NSEnumerateHashTable(clientsHash);
|
||||
while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
|
||||
|
@ -915,12 +920,20 @@ static int poolConnections = 0;
|
|||
{
|
||||
NSTimeInterval when = o->_lastOperation;
|
||||
|
||||
if (when < o->_lastStart)
|
||||
{
|
||||
when = o->_lastStart;
|
||||
}
|
||||
if (when < t && YES == o->connected)
|
||||
{
|
||||
[o disconnect];
|
||||
if (nil == a)
|
||||
{
|
||||
a = [NSMutableArray array];
|
||||
}
|
||||
[a addObject: o];
|
||||
}
|
||||
}
|
||||
if ([o connected] == YES)
|
||||
else if ([o connected] == YES)
|
||||
{
|
||||
connectionCount++;
|
||||
}
|
||||
|
@ -928,6 +941,40 @@ static int poolConnections = 0;
|
|||
NSEndHashTableEnumeration(&e);
|
||||
[clientsLock unlock];
|
||||
|
||||
/* Disconnect any clients idle too long
|
||||
*/
|
||||
while ([a count] > 0)
|
||||
{
|
||||
o = [a lastObject];
|
||||
if ([o->lock tryLock])
|
||||
{
|
||||
NSTimeInterval when = o->_lastOperation;
|
||||
|
||||
if (when < o->_lastStart)
|
||||
{
|
||||
when = o->_lastStart;
|
||||
}
|
||||
if (when < t && YES == o->connected)
|
||||
{
|
||||
NS_DURING
|
||||
{
|
||||
[o disconnect];
|
||||
if ([o connected] == YES)
|
||||
{
|
||||
connectionCount++;
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Problem disconnecting: %@", localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
[o->lock unlock];
|
||||
}
|
||||
[a removeLastObject];
|
||||
}
|
||||
|
||||
while (connectionCount >= (maxConnections + poolConnections))
|
||||
{
|
||||
SQLClient *other = nil;
|
||||
|
@ -942,11 +989,15 @@ static int poolConnections = 0;
|
|||
{
|
||||
NSTimeInterval when = o->_lastOperation;
|
||||
|
||||
if (when < o->_lastStart)
|
||||
{
|
||||
when = o->_lastStart;
|
||||
}
|
||||
connectionCount++;
|
||||
if (oldest == 0.0 || when < oldest)
|
||||
{
|
||||
oldest = when;
|
||||
other = o;
|
||||
ASSIGN(other, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -959,7 +1010,7 @@ static int poolConnections = 0;
|
|||
@"Force disconnect of '%@' because max connections (%u) reached",
|
||||
other, maxConnections];
|
||||
}
|
||||
[other disconnect];
|
||||
[AUTORELEASE(other) disconnect];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue