fixes for potential locking issues.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@36047 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2013-01-31 09:04:35 +00:00
parent 1f11ea97a9
commit 2e84577b69
2 changed files with 44 additions and 10 deletions

View file

@ -1,3 +1,12 @@
2013-01-31 Richard Frith-Macdonald <rfm@gnu.org>
* SQLClient.m: Check for -disconnect being called when inside a
transaction and handle locking properly in that case.
Change simple execute and query methods so they don't call -debug:
inside locked regions, in case the method has been overridden to
do something not safe in such locked sections (such as trying a
query in another thread to report extra debug info).
2012-11-29 Richard Frith-Macdonald <rfm@gnu.org> 2012-11-29 Richard Frith-Macdonald <rfm@gnu.org>
* Wrap more code in exception handlers where there is any potential * Wrap more code in exception handlers where there is any potential

View file

@ -1322,6 +1322,16 @@ static unsigned int maxConnections = 8;
NSNotificationCenter *nc; NSNotificationCenter *nc;
[lock lock]; [lock lock];
if (YES == _inTransaction)
{
/* If we are inside a transaction we must be doubly locked,
* so we do an unlock corresponding to the -begin before we
* disconnect (the disconnect implicitly rolls back the
* transaction).
*/
_inTransaction = NO;
[lock unlock];
}
if (connected == YES) if (connected == YES)
{ {
NS_DURING NS_DURING
@ -1850,6 +1860,7 @@ static unsigned int maxConnections = 8;
- (NSInteger) simpleExecute: (NSArray*)info - (NSInteger) simpleExecute: (NSArray*)info
{ {
NSInteger result; NSInteger result;
NSString *debug = nil;
[lock lock]; [lock lock];
NS_DURING NS_DURING
@ -1887,20 +1898,23 @@ static unsigned int maxConnections = 8;
if (isCommit || isRollback) if (isCommit || isRollback)
{ {
NSEnumerator *e = [_statements objectEnumerator]; NSEnumerator *e = [_statements objectEnumerator];
NSMutableString *m;
if (isCommit) if (isCommit)
{ {
[self debug: m = [NSMutableString stringWithFormat:
@"Duration %g for transaction commit ...", d]; @"Duration %g for transaction commit ...\n", d];
} }
else else
{ {
[self debug: m = [NSMutableString stringWithFormat:
@"Duration %g for transaction rollback ...", d]; @"Duration %g for transaction rollback ...\n", d];
} }
while ((statement = [e nextObject]) != nil) while ((statement = [e nextObject]) != nil)
{ {
[self debug: @" %@;", statement]; [m appendFormat: @" %@;\n", statement];
} }
debug = m;
} }
else if ([self debugging] > 1) else if ([self debugging] > 1)
{ {
@ -1908,12 +1922,13 @@ static unsigned int maxConnections = 8;
* For higher debug levels, we log data objects as well * For higher debug levels, we log data objects as well
* as the query string, otherwise we omit them. * as the query string, otherwise we omit them.
*/ */
[self debug: @"Duration %g for statement %@", d, info]; debug = [NSString stringWithFormat:
@"Duration %g for statement %@", d, info];
} }
else else
{ {
[self debug: @"Duration %g for statement %@", debug = [NSString stringWithFormat:
d, statement]; @"Duration %g for statement %@", d, statement];
} }
} }
} }
@ -1934,6 +1949,10 @@ static unsigned int maxConnections = 8;
} }
NS_ENDHANDLER NS_ENDHANDLER
[lock unlock]; [lock unlock];
if (nil != debug)
{
[self debug: @"%@", debug];
}
return result; return result;
} }
@ -1947,6 +1966,7 @@ static unsigned int maxConnections = 8;
listType: (id)ltype listType: (id)ltype
{ {
NSMutableArray *result = nil; NSMutableArray *result = nil;
NSString *debug = nil;
if (rtype == 0) rtype = rClass; if (rtype == 0) rtype = rClass;
if (ltype == 0) ltype = aClass; if (ltype == 0) ltype = aClass;
@ -1968,7 +1988,8 @@ static unsigned int maxConnections = 8;
d = _lastOperation - start; d = _lastOperation - start;
if (d >= _duration) if (d >= _duration)
{ {
[self debug: @"Duration %g for query %@", d, stmt]; debug = [NSString stringWithFormat:
@"Duration %g for query %@", d, stmt];
} }
} }
} }
@ -1979,6 +2000,10 @@ static unsigned int maxConnections = 8;
} }
NS_ENDHANDLER NS_ENDHANDLER
[lock unlock]; [lock unlock];
if (nil != debug)
{
[self debug: @"%@", debug];
}
return result; return result;
} }