mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-22 03:11:08 +00:00
thread-safety fixup
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@38110 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1ebf4e67b8
commit
94f90586bb
2 changed files with 63 additions and 27 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2014-10-07 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* SQLClient.m: Add locking of the database client by SQLTransaction
|
||||||
|
in case another thread tries to use the client whjile the transaction
|
||||||
|
is using it (ie between an attempted transaction and a rollback if
|
||||||
|
it fails).
|
||||||
|
|
||||||
2014-10-02 Richard Frith-Macdonald <rfm@gnu.org>
|
2014-10-02 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* SQLClient.m: On exception during SQLTransaction -execute, roll back.
|
* SQLClient.m: On exception during SQLTransaction -execute, roll back.
|
||||||
|
|
83
SQLClient.m
83
SQLClient.m
|
@ -648,12 +648,53 @@ static NSArray *rollbackStatement = nil;
|
||||||
|
|
||||||
|
|
||||||
@interface SQLClient (Private)
|
@interface SQLClient (Private)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to handle configuration using the notification object.
|
||||||
|
* This object may be either a configuration front end or a user defaults
|
||||||
|
* object ... so we have to be careful that we work with both.
|
||||||
|
*/
|
||||||
- (void) _configure: (NSNotification*)n;
|
- (void) _configure: (NSNotification*)n;
|
||||||
|
|
||||||
|
/** Internal method to make the client instance lock available to
|
||||||
|
* an associated SQLTransaction
|
||||||
|
*/
|
||||||
|
- (NSRecursiveLock*) _lock;
|
||||||
|
|
||||||
|
/** Internal method to populate the cache with the result of a query.
|
||||||
|
*/
|
||||||
- (void) _populateCache: (CacheQuery*)a;
|
- (void) _populateCache: (CacheQuery*)a;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to build an sql string by quoting any non-string objects
|
||||||
|
* and concatenating the resulting strings in a nil terminated list.<br />
|
||||||
|
* Returns an array containing the statement as the first object and
|
||||||
|
* any NSData objects following. The NSData objects appear in the
|
||||||
|
* statement strings as the marker sequence - <code>'?'''?'</code>
|
||||||
|
*/
|
||||||
- (NSMutableArray*) _prepare: (NSString*)stmt args: (va_list)args;
|
- (NSMutableArray*) _prepare: (NSString*)stmt args: (va_list)args;
|
||||||
|
|
||||||
|
/** Internal method called to record the 'main' thread in which automated
|
||||||
|
* cache updates are to be performed.
|
||||||
|
*/
|
||||||
- (void) _recordMainThread;
|
- (void) _recordMainThread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to substitute values from the dictionary into
|
||||||
|
* a string containing markup identifying where the values should
|
||||||
|
* appear by name. Non-string objects in the dictionary are quoted.<br />
|
||||||
|
* Returns an array containing the statement as the first object and
|
||||||
|
* any NSData objects following. The NSData objects appear in the
|
||||||
|
* statement strings as the marker sequence - <code>'?'''?'</code>
|
||||||
|
*/
|
||||||
- (NSMutableArray*) _substitute: (NSString*)str with: (NSDictionary*)vals;
|
- (NSMutableArray*) _substitute: (NSString*)str with: (NSDictionary*)vals;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called at one second intervals to ensure that our current timestamp
|
||||||
|
* is reasonably accurate.
|
||||||
|
*/
|
||||||
+ (void) _tick: (NSTimer*)t;
|
+ (void) _tick: (NSTimer*)t;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface SQLClient (GSCacheDelegate)
|
@interface SQLClient (GSCacheDelegate)
|
||||||
|
@ -2041,11 +2082,6 @@ static unsigned int maxConnections = 8;
|
||||||
|
|
||||||
@implementation SQLClient (Private)
|
@implementation SQLClient (Private)
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal method to handle configuration using the notification object.
|
|
||||||
* This object may be either a configuration front end or a user defaults
|
|
||||||
* object ... so we have to be careful that we work with both.
|
|
||||||
*/
|
|
||||||
- (void) _configure: (NSNotification*)n
|
- (void) _configure: (NSNotification*)n
|
||||||
{
|
{
|
||||||
NSDictionary *o;
|
NSDictionary *o;
|
||||||
|
@ -2203,8 +2239,11 @@ static unsigned int maxConnections = 8;
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Internal method to populate the cache with the result of a query.
|
- (NSRecursiveLock*) _lock
|
||||||
*/
|
{
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _populateCache: (CacheQuery*)a
|
- (void) _populateCache: (CacheQuery*)a
|
||||||
{
|
{
|
||||||
GSCache *cache;
|
GSCache *cache;
|
||||||
|
@ -2232,13 +2271,6 @@ static unsigned int maxConnections = 8;
|
||||||
lifetime: a->lifetime];
|
lifetime: a->lifetime];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal method to build an sql string by quoting any non-string objects
|
|
||||||
* and concatenating the resulting strings in a nil terminated list.<br />
|
|
||||||
* Returns an array containing the statement as the first object and
|
|
||||||
* any NSData objects following. The NSData objects appear in the
|
|
||||||
* statement strings as the marker sequence - <code>'?'''?'</code>
|
|
||||||
*/
|
|
||||||
- (NSMutableArray*) _prepare: (NSString*)stmt args: (va_list)args
|
- (NSMutableArray*) _prepare: (NSString*)stmt args: (va_list)args
|
||||||
{
|
{
|
||||||
NSMutableArray *ma = [NSMutableArray arrayWithCapacity: 2];
|
NSMutableArray *ma = [NSMutableArray arrayWithCapacity: 2];
|
||||||
|
@ -2285,14 +2317,6 @@ static unsigned int maxConnections = 8;
|
||||||
mainThread = [NSThread currentThread];
|
mainThread = [NSThread currentThread];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal method to substitute values from the dictionary into
|
|
||||||
* a string containing markup identifying where the values should
|
|
||||||
* appear by name. Non-string objects in the dictionary are quoted.<br />
|
|
||||||
* Returns an array containing the statement as the first object and
|
|
||||||
* any NSData objects following. The NSData objects appear in the
|
|
||||||
* statement strings as the marker sequence - <code>'?'''?'</code>
|
|
||||||
*/
|
|
||||||
- (NSMutableArray*) _substitute: (NSString*)str with: (NSDictionary*)vals
|
- (NSMutableArray*) _substitute: (NSString*)str with: (NSDictionary*)vals
|
||||||
{
|
{
|
||||||
unsigned int l = [str length];
|
unsigned int l = [str length];
|
||||||
|
@ -2467,10 +2491,6 @@ static unsigned int maxConnections = 8;
|
||||||
return ma;
|
return ma;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Called at one second intervals to ensure that our current timestamp
|
|
||||||
* is reasonably accurate.
|
|
||||||
*/
|
|
||||||
+ (void) _tick: (NSTimer*)t
|
+ (void) _tick: (NSTimer*)t
|
||||||
{
|
{
|
||||||
(void) GSTickerTimeNow();
|
(void) GSTickerTimeNow();
|
||||||
|
@ -3201,8 +3221,11 @@ static unsigned int maxConnections = 8;
|
||||||
if (_count > 0)
|
if (_count > 0)
|
||||||
{
|
{
|
||||||
NSMutableArray *info = nil;
|
NSMutableArray *info = nil;
|
||||||
BOOL wrap = [_db isInTransaction] ? NO : YES;
|
NSRecursiveLock *dbLock = [_db _lock];
|
||||||
|
BOOL wrap;
|
||||||
|
|
||||||
|
[dbLock lock];
|
||||||
|
wrap = [_db isInTransaction] ? NO : YES;
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
NSMutableString *sql;
|
NSMutableString *sql;
|
||||||
|
@ -3231,6 +3254,7 @@ static unsigned int maxConnections = 8;
|
||||||
|
|
||||||
[_db simpleExecute: info];
|
[_db simpleExecute: info];
|
||||||
[info release]; info = nil;
|
[info release]; info = nil;
|
||||||
|
[dbLock unlock];
|
||||||
}
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
|
@ -3250,6 +3274,7 @@ static unsigned int maxConnections = 8;
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
}
|
}
|
||||||
|
[dbLock unlock];
|
||||||
[e raise];
|
[e raise];
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
@ -3268,6 +3293,9 @@ static unsigned int maxConnections = 8;
|
||||||
|
|
||||||
if (_count > 0)
|
if (_count > 0)
|
||||||
{
|
{
|
||||||
|
NSRecursiveLock *dbLock = [_db _lock];
|
||||||
|
|
||||||
|
[dbLock lock];
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
[self execute];
|
[self execute];
|
||||||
|
@ -3370,6 +3398,7 @@ static unsigned int maxConnections = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
[dbLock unlock];
|
||||||
}
|
}
|
||||||
return executed;
|
return executed;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue