mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-20 18:32:06 +00:00
initial thread pool implementation
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@37950 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c738aae5bc
commit
dd264972c9
4 changed files with 143 additions and 280 deletions
|
@ -36,7 +36,7 @@ DOCUMENT_NAME=SQLClient
|
|||
|
||||
SQLClient_INTERFACE_VERSION=1.7
|
||||
|
||||
SQLClient_OBJC_FILES = SQLClient.m
|
||||
SQLClient_OBJC_FILES = SQLClient.m SQLClientPool.m
|
||||
SQLClient_LIBRARIES_DEPEND_UPON = -lPerformance
|
||||
SQLClient_HEADER_FILES = SQLClient.h
|
||||
SQLClient_AGSDOC_FILES = SQLClient.h
|
||||
|
|
68
SQLClient.h
68
SQLClient.h
|
@ -375,6 +375,7 @@ SQLCLIENT_PRIVATE
|
|||
* This should only be modified by the -setShouldTrim: method.
|
||||
*/
|
||||
BOOL _shouldTrim; /** Should whitespace be trimmed? */
|
||||
BOOL _forUseInPool; /** Should be used in a pool only */
|
||||
NSString *_name; /** Unique identifier for instance */
|
||||
NSString *_client; /** Identifier within backend */
|
||||
NSString *_database; /** The configured database name/host */
|
||||
|
@ -622,6 +623,13 @@ SQLCLIENT_PRIVATE
|
|||
*/
|
||||
- (id) initWithConfiguration: (NSDictionary*)config;
|
||||
|
||||
/**
|
||||
* Calls -initWithConfiguration:name:pool: passing NO to say the client is
|
||||
* not in a pool.
|
||||
*/
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference;
|
||||
|
||||
/**
|
||||
* Initialise using the supplied configuration, or if that is nil, try to
|
||||
* use values from NSUserDefaults (and automatically update when the
|
||||
|
@ -630,10 +638,10 @@ SQLCLIENT_PRIVATE
|
|||
* a nil name is supplied, defaults to the value of SQLClientName in the
|
||||
* configuration dictionary (or in the standard user defaults). If there is
|
||||
* no value for SQLClientName, uses the string 'Database'.<br />
|
||||
* If a SQLClient instance already exists with the name used for this
|
||||
* instance, the receiver is deallocated and the existing instance is
|
||||
* retained and returned ... there may only ever be one instance for a
|
||||
* particular reference name.<br />
|
||||
* If forUseInPool is NO and a SQLClient instance already exists with the
|
||||
* name used for this instance, the receiver is deallocated and the existing
|
||||
* instance is retained and returned ... there may only ever be one instance
|
||||
* for a particular reference name which is not in a pool.<br />
|
||||
* <br />
|
||||
* The config argument (or the SQLClientReferences user default)
|
||||
* is a dictionary with names as keys and dictionaries
|
||||
|
@ -653,7 +661,8 @@ SQLCLIENT_PRIVATE
|
|||
* connect to a database on a different host over the network.
|
||||
*/
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference;
|
||||
name: (NSString*)reference
|
||||
pool: (BOOL)forUseInPool;
|
||||
|
||||
/** Two clients are considered equal if they refer to the same database
|
||||
* and are logged in as the same database user using the same protocol.
|
||||
|
@ -1367,13 +1376,60 @@ SQLCLIENT_PRIVATE
|
|||
* asynchronous query to update them will be run on the cache thread.<br />
|
||||
* The rule is that, if the item's age is more than twice its nominal
|
||||
* lifetime, it will be retrieved immediately, otherwise it will be
|
||||
* retrieved asynchrnonously.<br />
|
||||
* retrieved asynchronously.<br />
|
||||
* Currently this may only be the main thread or nil. Any attempt to set
|
||||
* another thread will use the main thread instead.
|
||||
*/
|
||||
- (void) setCacheThread: (NSThread*)aThread;
|
||||
@end
|
||||
|
||||
/** <p>An SQLClientPool instance may be used to create/control a pool of
|
||||
* client objects. Code may obtain autoreleased proxies to the clients
|
||||
* from the pool and use them safe in the knowledge that they won't be
|
||||
* used anywhere else ... as soon as the proxy is deallocated the client
|
||||
* is returned to the pool.
|
||||
* </p>
|
||||
* <p>All clients in the pool share the same cache object, so query results
|
||||
* cached by one client will be available to other clients in the pool.
|
||||
* </p>
|
||||
*/
|
||||
@interface SQLClientPool : NSObject
|
||||
{
|
||||
NSConditionLock *lock; /** Controls access to the pool contents */
|
||||
SQLClient **c; /** The clients of the pool. */
|
||||
SQLClient **p; /** The proxies of the pool. */
|
||||
int max; /** Maximum connection count */
|
||||
int min; /** Minimum connection count */
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls -initWithConfiguration:name:pool: passing NO to say the client is
|
||||
* not in a pool.
|
||||
*/
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference
|
||||
max: (int)maxConnections
|
||||
min: (int)minConnections;
|
||||
|
||||
/** Fetches an (autoreleased) proxy to a client from the pool.
|
||||
*/
|
||||
- (SQLClient*) provideClient;
|
||||
|
||||
/**
|
||||
* Sets the cache for all the clients in the pool.
|
||||
*/
|
||||
- (void) setCache: (GSCache*)aCache;
|
||||
|
||||
/** Takes the client form the provided proxy and places it back
|
||||
* in the queue (so the proxy stops using it). This happens automatically
|
||||
* when the proxy is deallocated so you don't generally needs to do it.
|
||||
* Returns YES if the supplied proxy referred to a client in the pool,
|
||||
* NO otherwise.
|
||||
*/
|
||||
- (BOOL) swallowClient: (SQLClient*)proxy;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* The SQLTransaction transaction class provides a convenient mechanism
|
||||
* for grouping together a series of SQL statements to be executed as a
|
||||
|
|
346
SQLClient.m
346
SQLClient.m
|
@ -36,9 +36,9 @@
|
|||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSHashTable.h>
|
||||
#import <Foundation/NSKeyValueCoding.h>
|
||||
#import <Foundation/NSLock.h>
|
||||
#import <Foundation/NSHashTable.h>
|
||||
#import <Foundation/NSMapTable.h>
|
||||
#import <Foundation/NSNotification.h>
|
||||
#import <Foundation/NSNull.h>
|
||||
|
@ -105,237 +105,6 @@ static Class NSSetClass = 0;
|
|||
}
|
||||
@end
|
||||
|
||||
@interface SQLClientPool : NSObject
|
||||
{
|
||||
unsigned pool;
|
||||
NSString *name;
|
||||
NSString *serv;
|
||||
NSString *user;
|
||||
NSString *pass;
|
||||
NSString *path;
|
||||
NSHashTable *idle;
|
||||
NSHashTable *used;
|
||||
}
|
||||
- (BOOL) isSingle;
|
||||
- (BOOL) makeIdle: (SQLClient*)c;
|
||||
- (BOOL) makeUsed: (SQLClient*)c;
|
||||
- (void) setConfiguration: (NSDictionary*)o;
|
||||
@end
|
||||
|
||||
@implementation SQLClientPool
|
||||
- (void) dealloc
|
||||
{
|
||||
if (idle != 0)
|
||||
{
|
||||
NSFreeHashTable(idle);
|
||||
idle = 0;
|
||||
}
|
||||
if (used != 0)
|
||||
{
|
||||
NSFreeHashTable(used);
|
||||
used = 0;
|
||||
}
|
||||
[name release]; name = nil;
|
||||
[serv release]; serv = nil;
|
||||
[user release]; user = nil;
|
||||
[pass release]; pass = nil;
|
||||
[path release]; path = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference
|
||||
{
|
||||
name = [reference copy];
|
||||
idle = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 16);
|
||||
used = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 16);
|
||||
[self setConfiguration: config];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isSingle
|
||||
{
|
||||
if (pool == 1)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) makeIdle: (SQLClient*)c
|
||||
{
|
||||
if (NSHashGet(idle, (void*)c) == (void*)c)
|
||||
{
|
||||
return YES; // Already idle
|
||||
}
|
||||
if (NSHashGet(used, (void*)c) == (void*)c)
|
||||
{
|
||||
NSHashRemove(used, (void*)c);
|
||||
}
|
||||
if (NSCountHashTable(idle) + NSCountHashTable(used) < pool)
|
||||
{
|
||||
NSHashInsert(idle, (void*)c);
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) makeUsed: (SQLClient*)c
|
||||
{
|
||||
if (NSHashGet(used, (void*)c) == (void*)c)
|
||||
{
|
||||
return YES; // Already used
|
||||
}
|
||||
if (NSHashGet(idle, (void*)c) == (void*)c)
|
||||
{
|
||||
NSHashRemove(idle, (void*)c);
|
||||
}
|
||||
if (NSCountHashTable(idle) + NSCountHashTable(used) < pool)
|
||||
{
|
||||
NSHashInsert(used, (void*)c);
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) setConfiguration: (NSDictionary*)o
|
||||
{
|
||||
NSDictionary *d;
|
||||
NSString *s;
|
||||
BOOL change = NO;
|
||||
int capacity;
|
||||
|
||||
/*
|
||||
* get dictionary containing config info for this client by name.
|
||||
*/
|
||||
d = [o objectForKey: @"SQLClientReferences"];
|
||||
if ([d isKindOfClass: [NSDictionary class]] == NO)
|
||||
{
|
||||
d = nil;
|
||||
}
|
||||
d = [d objectForKey: name];
|
||||
if ([d isKindOfClass: [NSDictionary class]] == NO)
|
||||
{
|
||||
d = nil;
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"ServerType"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = @"Postgres";
|
||||
}
|
||||
if (s != serv && [s isEqual: serv] == NO)
|
||||
{
|
||||
s = [s copy];
|
||||
[serv release];
|
||||
serv = s;
|
||||
change = YES;
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"Database"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = [o objectForKey: @"Database"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = nil;
|
||||
}
|
||||
}
|
||||
if (s != path && [s isEqual: path] == NO)
|
||||
{
|
||||
s = [s copy];
|
||||
[path release];
|
||||
path = s;
|
||||
change = YES;
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"User"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = [o objectForKey: @"User"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = @"";
|
||||
}
|
||||
}
|
||||
if (s != user && [s isEqual: user] == NO)
|
||||
{
|
||||
s = [s copy];
|
||||
[user release];
|
||||
user = s;
|
||||
change = YES;
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"Password"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = [o objectForKey: @"Password"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = @"";
|
||||
}
|
||||
}
|
||||
if (s != pass && [s isEqual: pass] == NO)
|
||||
{
|
||||
s = [s copy];
|
||||
[pass release];
|
||||
pass = s;
|
||||
change = YES;
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"Password"];
|
||||
if ([s isKindOfClass: NSStringClass] == NO)
|
||||
{
|
||||
s = @"1";
|
||||
}
|
||||
capacity = [s intValue];
|
||||
if (capacity < 1) capacity = 1;
|
||||
if (capacity > 100) capacity = 100;
|
||||
|
||||
if (change == YES)
|
||||
{
|
||||
NSResetHashTable(idle);
|
||||
NSResetHashTable(used);
|
||||
}
|
||||
if (pool > capacity)
|
||||
{
|
||||
unsigned ic = NSCountHashTable(idle);
|
||||
unsigned uc = NSCountHashTable(used);
|
||||
|
||||
if (ic + uc > capacity)
|
||||
{
|
||||
NSHashEnumerator e = NSEnumerateHashTable(idle);
|
||||
void *c;
|
||||
|
||||
while (ic + uc > capacity
|
||||
&& (c = NSNextHashEnumeratorItem(&e)) != nil)
|
||||
{
|
||||
NSHashRemove(idle, c);
|
||||
ic--;
|
||||
}
|
||||
NSEndHashTableEnumeration(&e);
|
||||
if (uc > capacity)
|
||||
{
|
||||
NSHashEnumerator e = NSEnumerateHashTable(used);
|
||||
void *c;
|
||||
|
||||
while (uc > capacity
|
||||
&& (c = NSNextHashEnumeratorItem(&e)) != nil)
|
||||
{
|
||||
NSHashRemove(used, c);
|
||||
uc--;
|
||||
}
|
||||
NSEndHashTableEnumeration(&e);
|
||||
}
|
||||
}
|
||||
}
|
||||
pool = capacity;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
static Class aClass = 0;
|
||||
static Class rClass = 0;
|
||||
|
||||
|
@ -866,8 +635,9 @@ static NSTimeInterval classDuration = -1;
|
|||
/**
|
||||
* Container for all instances.
|
||||
*/
|
||||
static NSHashTable *clientsHash = 0;
|
||||
static NSMapTable *clientsMap = 0;
|
||||
static NSRecursiveLock *clientsMapLock = nil;
|
||||
static NSRecursiveLock *clientsLock = nil;
|
||||
static NSString *beginString = @"begin";
|
||||
static NSArray *beginStatement = nil;
|
||||
static NSString *commitString = @"commit";
|
||||
|
@ -898,11 +668,19 @@ static unsigned int maxConnections = 8;
|
|||
|
||||
+ (NSArray*) allClients
|
||||
{
|
||||
NSArray *a;
|
||||
NSMutableArray *a;
|
||||
NSHashEnumerator e;
|
||||
id o;
|
||||
|
||||
[clientsMapLock lock];
|
||||
a = NSAllMapTableValues(clientsMap);
|
||||
[clientsMapLock unlock];
|
||||
[clientsLock lock];
|
||||
a = [NSMutableArray arrayWithCapacity: NSCountHashTable(clientsHash)];
|
||||
e = NSEnumerateHashTable(clientsHash);
|
||||
while (nil != (o = (id)NSNextHashEnumeratorItem(&e)))
|
||||
{
|
||||
[a addObject: o];
|
||||
}
|
||||
NSEndHashTableEnumeration(&e);
|
||||
[clientsLock unlock];
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -951,10 +729,10 @@ static unsigned int maxConnections = 8;
|
|||
}
|
||||
}
|
||||
|
||||
[clientsMapLock lock];
|
||||
[clientsLock lock];
|
||||
existing = (SQLClient*)NSMapGet(clientsMap, reference);
|
||||
[[existing retain] autorelease];
|
||||
[clientsMapLock unlock];
|
||||
[clientsLock unlock];
|
||||
return existing;
|
||||
}
|
||||
|
||||
|
@ -966,11 +744,12 @@ static unsigned int maxConnections = 8;
|
|||
queryModes = [[NSArray alloc] initWithObjects: modes count: 1];
|
||||
GSTickerTimeNow();
|
||||
[SQLRecord class]; // Force initialisation
|
||||
if (clientsMap == 0)
|
||||
if (0 == clientsHash)
|
||||
{
|
||||
clientsHash = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 0);
|
||||
clientsMap = NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||
NSNonRetainedObjectMapValueCallBacks, 0);
|
||||
clientsMapLock = [NSRecursiveLock new];
|
||||
clientsLock = [NSRecursiveLock new];
|
||||
beginStatement = [[NSArray arrayWithObject: beginString] retain];
|
||||
commitStatement = [[NSArray arrayWithObject: commitString] retain];
|
||||
rollbackStatement = [[NSArray arrayWithObject: rollbackString] retain];
|
||||
|
@ -992,15 +771,14 @@ static unsigned int maxConnections = 8;
|
|||
|
||||
+ (void) purgeConnections: (NSDate*)since
|
||||
{
|
||||
NSMapEnumerator e;
|
||||
NSString *n;
|
||||
NSHashEnumerator e;
|
||||
SQLClient *o;
|
||||
unsigned int connectionCount = 0;
|
||||
NSTimeInterval t = [since timeIntervalSinceReferenceDate];
|
||||
|
||||
[clientsMapLock lock];
|
||||
e = NSEnumerateMapTable(clientsMap);
|
||||
while (NSNextMapEnumeratorPair(&e, (void**)&n, (void**)&o) != 0)
|
||||
[clientsLock lock];
|
||||
e = NSEnumerateHashTable(clientsHash);
|
||||
while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
|
||||
{
|
||||
if (since != nil)
|
||||
{
|
||||
|
@ -1016,8 +794,8 @@ static unsigned int maxConnections = 8;
|
|||
connectionCount++;
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&e);
|
||||
[clientsMapLock unlock];
|
||||
NSEndHashTableEnumeration(&e);
|
||||
[clientsLock unlock];
|
||||
|
||||
while (connectionCount >= maxConnections)
|
||||
{
|
||||
|
@ -1025,9 +803,9 @@ static unsigned int maxConnections = 8;
|
|||
NSTimeInterval oldest = 0.0;
|
||||
|
||||
connectionCount = 0;
|
||||
[clientsMapLock lock];
|
||||
e = NSEnumerateMapTable(clientsMap);
|
||||
while (NSNextMapEnumeratorPair(&e, (void**)&n, (void**)&o))
|
||||
[clientsLock lock];
|
||||
e = NSEnumerateHashTable(clientsHash);
|
||||
while (nil != (o = (SQLClient*)NSNextHashEnumeratorItem(&e)))
|
||||
{
|
||||
if ([o connected] == YES)
|
||||
{
|
||||
|
@ -1041,8 +819,8 @@ static unsigned int maxConnections = 8;
|
|||
}
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&e);
|
||||
[clientsMapLock unlock];
|
||||
NSEndHashTableEnumeration(&e);
|
||||
[clientsLock unlock];
|
||||
connectionCount--;
|
||||
if ([other debugging] > 0)
|
||||
{
|
||||
|
@ -1233,12 +1011,13 @@ static unsigned int maxConnections = 8;
|
|||
{
|
||||
NSNotificationCenter *nc;
|
||||
|
||||
if (_name != nil)
|
||||
[clientsLock lock];
|
||||
NSHashRemove(clientsHash, (void*)self);
|
||||
if (_name != nil && NO == _forUseInPool)
|
||||
{
|
||||
[clientsMapLock lock];
|
||||
NSMapRemove(clientsMap, (void*)_name);
|
||||
[clientsMapLock unlock];
|
||||
}
|
||||
[clientsLock unlock];
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
[nc removeObserver: self];
|
||||
[self disconnect];
|
||||
|
@ -1381,6 +1160,14 @@ static unsigned int maxConnections = 8;
|
|||
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference
|
||||
{
|
||||
return [self initWithConfiguration: config name: reference pool: NO];
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithConfiguration: (NSDictionary*)config
|
||||
name: (NSString*)reference
|
||||
pool: (BOOL)forUseInPool
|
||||
{
|
||||
NSNotification *n;
|
||||
NSDictionary *conf = config;
|
||||
|
@ -1401,8 +1188,16 @@ static unsigned int maxConnections = 8;
|
|||
}
|
||||
}
|
||||
|
||||
[clientsMapLock lock];
|
||||
existing = (SQLClient*)NSMapGet(clientsMap, reference);
|
||||
[clientsLock lock];
|
||||
_forUseInPool = (NO == forUseInPool) ? NO : YES;
|
||||
if (YES == _forUseInPool)
|
||||
{
|
||||
existing = (SQLClient*)NSMapGet(clientsMap, reference);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing = nil;
|
||||
}
|
||||
if (nil == existing)
|
||||
{
|
||||
lock = [NSRecursiveLock new]; // Ensure thread-safety.
|
||||
|
@ -1426,6 +1221,7 @@ static unsigned int maxConnections = 8;
|
|||
object: conf
|
||||
userInfo: nil];
|
||||
|
||||
NSHashInsert(clientsHash, (void*)self);
|
||||
[self _configure: n]; // Actually set up the configuration.
|
||||
}
|
||||
else
|
||||
|
@ -1433,7 +1229,7 @@ static unsigned int maxConnections = 8;
|
|||
[self release];
|
||||
self = [existing retain];
|
||||
}
|
||||
[clientsMapLock unlock];
|
||||
[clientsLock unlock];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -1733,12 +1529,12 @@ static unsigned int maxConnections = 8;
|
|||
* it from the table so that no other thread will find it
|
||||
* and try to use it while it is being deallocated.
|
||||
*/
|
||||
[clientsMapLock lock];
|
||||
[clientsLock lock];
|
||||
if (NSDecrementExtraRefCountWasZero(self))
|
||||
{
|
||||
[self dealloc];
|
||||
}
|
||||
[clientsMapLock unlock];
|
||||
[clientsLock unlock];
|
||||
}
|
||||
|
||||
- (void) rollback
|
||||
|
@ -1803,24 +1599,27 @@ static unsigned int maxConnections = 8;
|
|||
{
|
||||
if ([s isEqual: _name] == NO)
|
||||
{
|
||||
[clientsMapLock lock];
|
||||
if (NSMapGet(clientsMap, s) != 0)
|
||||
[clientsLock lock];
|
||||
if (NO == _forUseInPool)
|
||||
{
|
||||
[clientsMapLock unlock];
|
||||
[lock unlock];
|
||||
if ([self debugging] > 0)
|
||||
if (NSMapGet(clientsMap, s) != 0)
|
||||
{
|
||||
[self debug: @"Error attempt to re-use client name %@", s];
|
||||
[clientsLock unlock];
|
||||
[lock unlock];
|
||||
if ([self debugging] > 0)
|
||||
{
|
||||
[self
|
||||
debug: @"Error attempt to re-use client name %@", s];
|
||||
}
|
||||
NS_VOIDRETURN;
|
||||
}
|
||||
NS_VOIDRETURN;
|
||||
}
|
||||
if (connected == YES)
|
||||
{
|
||||
[self disconnect];
|
||||
}
|
||||
if (_name != nil)
|
||||
if (NO == _forUseInPool && _name != nil)
|
||||
{
|
||||
[[self retain] autorelease];
|
||||
NSMapRemove(clientsMap, (void*)_name);
|
||||
}
|
||||
s = [s copy];
|
||||
|
@ -1828,8 +1627,11 @@ static unsigned int maxConnections = 8;
|
|||
_name = s;
|
||||
[_client release];
|
||||
_client = [[[NSProcessInfo processInfo] globallyUniqueString] retain];
|
||||
NSMapInsert(clientsMap, (void*)_name, (void*)self);
|
||||
[clientsMapLock unlock];
|
||||
if (NO == _forUseInPool && _name != nil)
|
||||
{
|
||||
NSMapInsert(clientsMap, (void*)_name, (void*)self);
|
||||
}
|
||||
[clientsLock unlock];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
|
|
|
@ -42,6 +42,7 @@ int
|
|||
main()
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
SQLClientPool *sp;
|
||||
SQLClient *db;
|
||||
NSUserDefaults *defs;
|
||||
NSMutableArray *records;
|
||||
|
@ -68,7 +69,11 @@ main()
|
|||
nil]
|
||||
];
|
||||
|
||||
db = [SQLClient clientWithConfiguration: nil name: @"test"];
|
||||
sp = [[SQLClientPool alloc] initWithConfiguration: nil
|
||||
name: @"test"
|
||||
max: 2
|
||||
min: 1];
|
||||
db = [[sp autorelease] provideClient];
|
||||
|
||||
l = [Logger new];
|
||||
[[NSNotificationCenter defaultCenter] addObserver: l
|
||||
|
|
Loading…
Reference in a new issue