mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-15 16:11:42 +00:00
lock safety fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@35832 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1fdb15cfb0
commit
1f11ea97a9
2 changed files with 162 additions and 110 deletions
|
@ -1,3 +1,8 @@
|
|||
2012-11-29 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Wrap more code in exception handlers where there is any potential
|
||||
for an exception in a lock protected region.
|
||||
|
||||
2012-11-10 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* GNUmakefile: Link against $(FND_LIBS) and $(OBJC_LIBS) instead
|
||||
|
|
267
SQLClient.m
267
SQLClient.m
|
@ -1162,25 +1162,26 @@ static unsigned int maxConnections = 8;
|
|||
[lock lock];
|
||||
if (connected == NO)
|
||||
{
|
||||
if (_connectFails > 1)
|
||||
{
|
||||
NSTimeInterval delay;
|
||||
NSTimeInterval elapsed;
|
||||
|
||||
/* If we have repeated connection failures, we enforce a
|
||||
* delay of up to 30 seconds between connection attempts
|
||||
* to avoid overloading the system with too frequent
|
||||
* connection attempts.
|
||||
*/
|
||||
delay = (_connectFails < 30) ? _connectFails : 30;
|
||||
elapsed = GSTickerTimeNow() - _lastOperation;
|
||||
if (elapsed < delay)
|
||||
{
|
||||
[NSThread sleepForTimeInterval: delay - elapsed];
|
||||
}
|
||||
}
|
||||
NS_DURING
|
||||
{
|
||||
if (_connectFails > 1)
|
||||
{
|
||||
NSTimeInterval delay;
|
||||
NSTimeInterval elapsed;
|
||||
|
||||
/* If we have repeated connection failures, we enforce a
|
||||
* delay of up to 30 seconds between connection attempts
|
||||
* to avoid overloading the system with too frequent
|
||||
* connection attempts.
|
||||
*/
|
||||
delay = (_connectFails < 30) ? _connectFails : 30;
|
||||
elapsed = GSTickerTimeNow() - _lastOperation;
|
||||
if (elapsed < delay)
|
||||
{
|
||||
[NSThread sleepForTimeInterval: delay - elapsed];
|
||||
}
|
||||
}
|
||||
|
||||
[self backendConnect];
|
||||
/* On establishng a new connection, we must restore any
|
||||
* listen instructions in the backend.
|
||||
|
@ -1284,22 +1285,32 @@ static unsigned int maxConnections = 8;
|
|||
NSMutableString *s = [[NSMutableString new] autorelease];
|
||||
|
||||
[lock lock];
|
||||
[s appendFormat: @"Database - %@\n", [self clientName]];
|
||||
[s appendFormat: @" Name - %@\n", [self name]];
|
||||
[s appendFormat: @" DBase - %@\n", [self database]];
|
||||
[s appendFormat: @" DB User - %@\n", [self user]];
|
||||
[s appendFormat: @" Password - %@\n",
|
||||
[self password] == nil ? @"unknown" : @"known"];
|
||||
[s appendFormat: @" Connected - %@\n", connected ? @"yes" : @"no"];
|
||||
[s appendFormat: @" Transaction - %@\n", _inTransaction ? @"yes" : @"no"];
|
||||
if (_cache == nil)
|
||||
NS_DURING
|
||||
{
|
||||
[s appendString: @"\n"];
|
||||
[s appendFormat: @"Database - %@\n", [self clientName]];
|
||||
[s appendFormat: @" Name - %@\n", [self name]];
|
||||
[s appendFormat: @" DBase - %@\n", [self database]];
|
||||
[s appendFormat: @" DB User - %@\n", [self user]];
|
||||
[s appendFormat: @" Password - %@\n",
|
||||
[self password] == nil ? @"unknown" : @"known"];
|
||||
[s appendFormat: @" Connected - %@\n", connected ? @"yes" : @"no"];
|
||||
[s appendFormat: @" Transaction - %@\n",
|
||||
_inTransaction ? @"yes" : @"no"];
|
||||
if (_cache == nil)
|
||||
{
|
||||
[s appendString: @"\n"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[s appendFormat: @" Cache - %@\n", _cache];
|
||||
}
|
||||
}
|
||||
else
|
||||
NS_HANDLER
|
||||
{
|
||||
[s appendFormat: @" Cache - %@\n", _cache];
|
||||
[lock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[lock unlock];
|
||||
return s;
|
||||
}
|
||||
|
@ -1838,26 +1849,26 @@ static unsigned int maxConnections = 8;
|
|||
|
||||
- (NSInteger) simpleExecute: (NSArray*)info
|
||||
{
|
||||
NSString *statement;
|
||||
NSInteger result;
|
||||
BOOL isCommit = NO;
|
||||
BOOL isRollback = NO;
|
||||
|
||||
[lock lock];
|
||||
statement = [info objectAtIndex: 0];
|
||||
|
||||
if ([statement isEqualToString: commitString])
|
||||
{
|
||||
isCommit = YES;
|
||||
}
|
||||
if ([statement isEqualToString: rollbackString])
|
||||
{
|
||||
isRollback = YES;
|
||||
}
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
NSTimeInterval start = 0.0;
|
||||
NSString *statement;
|
||||
BOOL isCommit = NO;
|
||||
BOOL isRollback = NO;
|
||||
|
||||
statement = [info objectAtIndex: 0];
|
||||
|
||||
if ([statement isEqualToString: commitString])
|
||||
{
|
||||
isCommit = YES;
|
||||
}
|
||||
if ([statement isEqualToString: rollbackString])
|
||||
{
|
||||
isRollback = YES;
|
||||
}
|
||||
|
||||
if (_duration >= 0)
|
||||
{
|
||||
|
@ -2877,17 +2888,26 @@ static unsigned int maxConnections = 8;
|
|||
- (void) setCache: (GSCache*)aCache
|
||||
{
|
||||
[lock lock];
|
||||
if (_cacheThread != nil)
|
||||
NS_DURING
|
||||
{
|
||||
[_cache setDelegate: nil];
|
||||
if (_cacheThread != nil)
|
||||
{
|
||||
[_cache setDelegate: nil];
|
||||
}
|
||||
[aCache retain];
|
||||
[_cache release];
|
||||
_cache = aCache;
|
||||
if (_cacheThread != nil)
|
||||
{
|
||||
[_cache setDelegate: self];
|
||||
}
|
||||
}
|
||||
[aCache retain];
|
||||
[_cache release];
|
||||
_cache = aCache;
|
||||
if (_cacheThread != nil)
|
||||
NS_HANDLER
|
||||
{
|
||||
[_cache setDelegate: self];
|
||||
[lock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[lock unlock];
|
||||
}
|
||||
|
||||
|
@ -2906,17 +2926,26 @@ static unsigned int maxConnections = 8;
|
|||
aThread = mainThread;
|
||||
}
|
||||
[lock lock];
|
||||
if (_cacheThread != nil)
|
||||
NS_DURING
|
||||
{
|
||||
[_cache setDelegate: nil];
|
||||
if (_cacheThread != nil)
|
||||
{
|
||||
[_cache setDelegate: nil];
|
||||
}
|
||||
[aThread retain];
|
||||
[_cacheThread release];
|
||||
_cacheThread = aThread;
|
||||
if (_cacheThread != nil)
|
||||
{
|
||||
[_cache setDelegate: self];
|
||||
}
|
||||
}
|
||||
[aThread retain];
|
||||
[_cacheThread release];
|
||||
_cacheThread = aThread;
|
||||
if (_cacheThread != nil)
|
||||
NS_HANDLER
|
||||
{
|
||||
[_cache setDelegate: self];
|
||||
[lock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[lock unlock];
|
||||
}
|
||||
@end
|
||||
|
@ -3342,34 +3371,43 @@ validName(NSString *name)
|
|||
|
||||
name = validName(name);
|
||||
[lock lock];
|
||||
if (nil == _observers)
|
||||
NS_DURING
|
||||
{
|
||||
_observers = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
_names = [NSCountedSet new];
|
||||
}
|
||||
set = (NSMutableSet*)NSMapGet(_observers, (void*)anObserver);
|
||||
if (nil == set)
|
||||
{
|
||||
set = [NSMutableSet new];
|
||||
NSMapInsert(_observers, anObserver, set);
|
||||
[set release];
|
||||
}
|
||||
if (nil == [set member: name])
|
||||
{
|
||||
NSUInteger count = [_names countForObject: name];
|
||||
|
||||
[set addObject: name];
|
||||
[_names addObject: name];
|
||||
if (0 == count)
|
||||
if (nil == _observers)
|
||||
{
|
||||
[self backendListen: name];
|
||||
_observers = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
_names = [NSCountedSet new];
|
||||
}
|
||||
set = (NSMutableSet*)NSMapGet(_observers, (void*)anObserver);
|
||||
if (nil == set)
|
||||
{
|
||||
set = [NSMutableSet new];
|
||||
NSMapInsert(_observers, anObserver, set);
|
||||
[set release];
|
||||
}
|
||||
if (nil == [set member: name])
|
||||
{
|
||||
NSUInteger count = [_names countForObject: name];
|
||||
|
||||
[set addObject: name];
|
||||
[_names addObject: name];
|
||||
if (0 == count)
|
||||
{
|
||||
[self backendListen: name];
|
||||
}
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] addObserver: anObserver
|
||||
selector: aSelector
|
||||
name: name
|
||||
object: self];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] addObserver: anObserver
|
||||
selector: aSelector
|
||||
name: name
|
||||
object: self];
|
||||
NS_HANDLER
|
||||
{
|
||||
[lock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[lock unlock];
|
||||
}
|
||||
|
||||
|
@ -3394,41 +3432,50 @@ validName(NSString *name)
|
|||
name = validName(name);
|
||||
}
|
||||
[lock lock];
|
||||
if (_observers != nil)
|
||||
NS_DURING
|
||||
{
|
||||
NSNotificationCenter *nc;
|
||||
NSMutableSet *set;
|
||||
NSEnumerator *e;
|
||||
if (_observers != nil)
|
||||
{
|
||||
NSNotificationCenter *nc;
|
||||
NSMutableSet *set;
|
||||
NSEnumerator *e;
|
||||
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
set = (NSMutableSet*)NSMapGet(_observers, (void*)anObserver);
|
||||
if (nil == name)
|
||||
{
|
||||
e = [[set allObjects] objectEnumerator];
|
||||
name = [e nextObject];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = [[name retain] autorelease];
|
||||
}
|
||||
while (nil != name)
|
||||
{
|
||||
if (nil != [set member: name])
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
set = (NSMutableSet*)NSMapGet(_observers, (void*)anObserver);
|
||||
if (nil == name)
|
||||
{
|
||||
[nc removeObserver: anObserver
|
||||
name: name
|
||||
object: self];
|
||||
[[name retain] autorelease];
|
||||
[set removeObject: name];
|
||||
[_names removeObject: name];
|
||||
if (0 == [_names countForObject: name])
|
||||
{
|
||||
[self backendUnlisten: name];
|
||||
}
|
||||
e = [[set allObjects] objectEnumerator];
|
||||
name = [e nextObject];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = [[name retain] autorelease];
|
||||
}
|
||||
while (nil != name)
|
||||
{
|
||||
if (nil != [set member: name])
|
||||
{
|
||||
[nc removeObserver: anObserver
|
||||
name: name
|
||||
object: self];
|
||||
[[name retain] autorelease];
|
||||
[set removeObject: name];
|
||||
[_names removeObject: name];
|
||||
if (0 == [_names countForObject: name])
|
||||
{
|
||||
[self backendUnlisten: name];
|
||||
}
|
||||
}
|
||||
name = [e nextObject];
|
||||
}
|
||||
name = [e nextObject];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
[lock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[lock unlock];
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue