mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-19 10:00:59 +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>
|
2015-05-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* SQLClient.h: Add pool purge control method.
|
* 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
|
+ (void) purgeConnections: (NSDate*)since
|
||||||
{
|
{
|
||||||
NSHashEnumerator e;
|
NSHashEnumerator e;
|
||||||
|
NSMutableArray *a = nil;
|
||||||
SQLClient *o;
|
SQLClient *o;
|
||||||
unsigned int connectionCount = 0;
|
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];
|
[clientsLock lock];
|
||||||
e = NSEnumerateHashTable(clientsHash);
|
e = NSEnumerateHashTable(clientsHash);
|
||||||
while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
|
while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
|
||||||
|
@ -915,12 +920,20 @@ static int poolConnections = 0;
|
||||||
{
|
{
|
||||||
NSTimeInterval when = o->_lastOperation;
|
NSTimeInterval when = o->_lastOperation;
|
||||||
|
|
||||||
|
if (when < o->_lastStart)
|
||||||
|
{
|
||||||
|
when = o->_lastStart;
|
||||||
|
}
|
||||||
if (when < t && YES == o->connected)
|
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++;
|
connectionCount++;
|
||||||
}
|
}
|
||||||
|
@ -928,6 +941,40 @@ static int poolConnections = 0;
|
||||||
NSEndHashTableEnumeration(&e);
|
NSEndHashTableEnumeration(&e);
|
||||||
[clientsLock unlock];
|
[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))
|
while (connectionCount >= (maxConnections + poolConnections))
|
||||||
{
|
{
|
||||||
SQLClient *other = nil;
|
SQLClient *other = nil;
|
||||||
|
@ -942,11 +989,15 @@ static int poolConnections = 0;
|
||||||
{
|
{
|
||||||
NSTimeInterval when = o->_lastOperation;
|
NSTimeInterval when = o->_lastOperation;
|
||||||
|
|
||||||
|
if (when < o->_lastStart)
|
||||||
|
{
|
||||||
|
when = o->_lastStart;
|
||||||
|
}
|
||||||
connectionCount++;
|
connectionCount++;
|
||||||
if (oldest == 0.0 || when < oldest)
|
if (oldest == 0.0 || when < oldest)
|
||||||
{
|
{
|
||||||
oldest = when;
|
oldest = when;
|
||||||
other = o;
|
ASSIGN(other, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -959,7 +1010,7 @@ static int poolConnections = 0;
|
||||||
@"Force disconnect of '%@' because max connections (%u) reached",
|
@"Force disconnect of '%@' because max connections (%u) reached",
|
||||||
other, maxConnections];
|
other, maxConnections];
|
||||||
}
|
}
|
||||||
[other disconnect];
|
[AUTORELEASE(other) disconnect];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue