Author: rfm
Date: Tue Jun 9 18:47:36 2015
New Revision: 38606
URL: http://svn.gna.org/viewcvs/gnustep?rev=38606&view=rev
Log:
Attempted deadlock fix
Modified:
libs/sqlclient/trunk/ChangeLog
libs/sqlclient/trunk/SQLClient.m
Modified: libs/sqlclient/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/ChangeLog?rev=38606&r1=38605&r2=38606&view=diff
==============================================================================
--- libs/sqlclient/trunk/ChangeLog (original)
+++ libs/sqlclient/trunk/ChangeLog Tue Jun 9 18:47:36 2015
@@ -1,3 +1,9 @@
+2015-06-09 Richard Frith-Macdonald <[email protected]>
+
+ * 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 <[email protected]>
* SQLClient.h: Add pool purge control method.
Modified: libs/sqlclient/trunk/SQLClient.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=38606&r1=38605&r2=38606&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m (original)
+++ libs/sqlclient/trunk/SQLClient.m Tue Jun 9 18:47:36 2015
@@ -903,10 +903,15 @@
+ (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,18 +920,60 @@
{
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++;
}
}
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))
{
@@ -942,11 +989,15 @@
{
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 @@
@"Force disconnect of '%@' because max connections (%u) reached",
other, maxConnections];
}
- [other disconnect];
+ [AUTORELEASE(other) disconnect];
}
}
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs