Author: rfm
Date: Tue Oct 7 11:15:16 2014
New Revision: 38110
URL: http://svn.gna.org/viewcvs/gnustep?rev=38110&view=rev
Log:
thread-safety fixup
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=38110&r1=38109&r2=38110&view=diff
==============================================================================
--- libs/sqlclient/trunk/ChangeLog (original)
+++ libs/sqlclient/trunk/ChangeLog Tue Oct 7 11:15:16 2014
@@ -1,3 +1,10 @@
+2014-10-07 Richard Frith-Macdonald <[email protected]>
+
+ * 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 <[email protected]>
* SQLClient.m: On exception during SQLTransaction -execute, roll back.
Modified: libs/sqlclient/trunk/SQLClient.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=38110&r1=38109&r2=38110&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m (original)
+++ libs/sqlclient/trunk/SQLClient.m Tue Oct 7 11:15:16 2014
@@ -648,12 +648,53 @@
@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;
+
+/** 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;
+
+/**
+ * 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;
+
+/** Internal method called to record the 'main' thread in which automated
+ * cache updates are to be performed.
+ */
- (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;
+
+/*
+ * Called at one second intervals to ensure that our current timestamp
+ * is reasonably accurate.
+ */
+ (void) _tick: (NSTimer*)t;
+
@end
@interface SQLClient (GSCacheDelegate)
@@ -2041,11 +2082,6 @@
@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
{
NSDictionary *o;
@@ -2203,8 +2239,11 @@
[lock unlock];
}
-/** Internal method to populate the cache with the result of a query.
- */
+- (NSRecursiveLock*) _lock
+{
+ return lock;
+}
+
- (void) _populateCache: (CacheQuery*)a
{
GSCache *cache;
@@ -2232,13 +2271,6 @@
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 *ma = [NSMutableArray arrayWithCapacity: 2];
@@ -2285,14 +2317,6 @@
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
{
unsigned int l = [str length];
@@ -2467,10 +2491,6 @@
return ma;
}
-/*
- * Called at one second intervals to ensure that our current timestamp
- * is reasonably accurate.
- */
+ (void) _tick: (NSTimer*)t
{
(void) GSTickerTimeNow();
@@ -3201,8 +3221,11 @@
if (_count > 0)
{
NSMutableArray *info = nil;
- BOOL wrap = [_db isInTransaction] ? NO : YES;
-
+ NSRecursiveLock *dbLock = [_db _lock];
+ BOOL wrap;
+
+ [dbLock lock];
+ wrap = [_db isInTransaction] ? NO : YES;
NS_DURING
{
NSMutableString *sql;
@@ -3231,6 +3254,7 @@
[_db simpleExecute: info];
[info release]; info = nil;
+ [dbLock unlock];
}
NS_HANDLER
{
@@ -3250,6 +3274,7 @@
}
NS_ENDHANDLER
}
+ [dbLock unlock];
[e raise];
}
NS_ENDHANDLER
@@ -3268,6 +3293,9 @@
if (_count > 0)
{
+ NSRecursiveLock *dbLock = [_db _lock];
+
+ [dbLock lock];
NS_DURING
{
[self execute];
@@ -3370,6 +3398,7 @@
}
}
NS_ENDHANDLER
+ [dbLock unlock];
}
return executed;
}
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs