Ben Copsey

More thread safety tweaks for intial setup stuff (closes gh-148)

@@ -34,9 +34,12 @@ static NSString *permanentCacheFolder = @"PermanentStore"; @@ -34,9 +34,12 @@ static NSString *permanentCacheFolder = @"PermanentStore";
34 + (id)sharedCache 34 + (id)sharedCache
35 { 35 {
36 if (!sharedCache) { 36 if (!sharedCache) {
37 - sharedCache = [[self alloc] init]; 37 + @synchronized(self) {
38 - [sharedCache setStoragePath:[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"ASIHTTPRequestCache"]]; 38 + if (!sharedCache) {
39 - 39 + sharedCache = [[self alloc] init];
  40 + [sharedCache setStoragePath:[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"ASIHTTPRequestCache"]];
  41 + }
  42 + }
40 } 43 }
41 return sharedCache; 44 return sharedCache;
42 } 45 }
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 #import "ASIDataCompressor.h" 24 #import "ASIDataCompressor.h"
25 25
26 // Automatically set on build 26 // Automatically set on build
27 -NSString *ASIHTTPRequestVersion = @"v1.8.1-5 2011-06-05"; 27 +NSString *ASIHTTPRequestVersion = @"v1.8.1-8 2011-06-05";
28 28
29 static NSString *defaultUserAgent = nil; 29 static NSString *defaultUserAgent = nil;
30 30
@@ -4297,13 +4297,15 @@ static NSOperationQueue *sharedQueue = nil; @@ -4297,13 +4297,15 @@ static NSOperationQueue *sharedQueue = nil;
4297 } 4297 }
4298 } 4298 }
4299 4299
4300 -  
4301 + (NSMutableArray *)sessionCookies 4300 + (NSMutableArray *)sessionCookies
4302 { 4301 {
  4302 + [sessionCookiesLock lock];
4303 if (!sessionCookies) { 4303 if (!sessionCookies) {
4304 - [ASIHTTPRequest setSessionCookies:[[[NSMutableArray alloc] init] autorelease]]; 4304 + [ASIHTTPRequest setSessionCookies:[NSMutableArray array]];
4305 } 4305 }
4306 - return sessionCookies; 4306 + NSMutableArray *cookies = [[sessionCookies retain] autorelease];
  4307 + [sessionCookiesLock unlock];
  4308 + return cookies;
4307 } 4309 }
4308 4310
4309 + (void)setSessionCookies:(NSMutableArray *)newSessionCookies 4311 + (void)setSessionCookies:(NSMutableArray *)newSessionCookies
@@ -4349,81 +4351,83 @@ static NSOperationQueue *sharedQueue = nil; @@ -4349,81 +4351,83 @@ static NSOperationQueue *sharedQueue = nil;
4349 4351
4350 + (NSString *)defaultUserAgentString 4352 + (NSString *)defaultUserAgentString
4351 { 4353 {
4352 - // If we already have a default user agent set, return that 4354 + @synchronized (self) {
4353 - if (defaultUserAgent) {  
4354 - return defaultUserAgent;  
4355 - }  
4356 -  
4357 - // Otherwise, create a new user agent string (we'll save it for later reuse)  
4358 -  
4359 - NSBundle *bundle = [NSBundle bundleForClass:[self class]];  
4360 4355
4361 - // Attempt to find a name for this application 4356 + if (!defaultUserAgent) {
4362 - NSString *appName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];  
4363 - if (!appName) {  
4364 - appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];  
4365 - }  
4366 4357
4367 - NSData *latin1Data = [appName dataUsingEncoding:NSUTF8StringEncoding]; 4358 + NSBundle *bundle = [NSBundle bundleForClass:[self class]];
4368 - appName = [[[NSString alloc] initWithData:latin1Data encoding:NSISOLatin1StringEncoding] autorelease];  
4369 4359
4370 - // If we couldn't find one, we'll give up (and ASIHTTPRequest will use the standard CFNetwork user agent) 4360 + // Attempt to find a name for this application
4371 - if (!appName) { 4361 + NSString *appName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
4372 - return nil; 4362 + if (!appName) {
4373 - } 4363 + appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
  4364 + }
4374 4365
4375 - NSString *appVersion = nil; 4366 + NSData *latin1Data = [appName dataUsingEncoding:NSUTF8StringEncoding];
4376 - NSString *marketingVersionNumber = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 4367 + appName = [[[NSString alloc] initWithData:latin1Data encoding:NSISOLatin1StringEncoding] autorelease];
4377 - NSString *developmentVersionNumber = [bundle objectForInfoDictionaryKey:@"CFBundleVersion"]; 4368 +
4378 - if (marketingVersionNumber && developmentVersionNumber) { 4369 + // If we couldn't find one, we'll give up (and ASIHTTPRequest will use the standard CFNetwork user agent)
4379 - if ([marketingVersionNumber isEqualToString:developmentVersionNumber]) { 4370 + if (!appName) {
4380 - appVersion = marketingVersionNumber; 4371 + return nil;
4381 - } else { 4372 + }
4382 - appVersion = [NSString stringWithFormat:@"%@ rv:%@",marketingVersionNumber,developmentVersionNumber]; 4373 +
  4374 + NSString *appVersion = nil;
  4375 + NSString *marketingVersionNumber = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  4376 + NSString *developmentVersionNumber = [bundle objectForInfoDictionaryKey:@"CFBundleVersion"];
  4377 + if (marketingVersionNumber && developmentVersionNumber) {
  4378 + if ([marketingVersionNumber isEqualToString:developmentVersionNumber]) {
  4379 + appVersion = marketingVersionNumber;
  4380 + } else {
  4381 + appVersion = [NSString stringWithFormat:@"%@ rv:%@",marketingVersionNumber,developmentVersionNumber];
  4382 + }
  4383 + } else {
  4384 + appVersion = (marketingVersionNumber ? marketingVersionNumber : developmentVersionNumber);
  4385 + }
  4386 +
  4387 + NSString *deviceName;
  4388 + NSString *OSName;
  4389 + NSString *OSVersion;
  4390 + NSString *locale = [[NSLocale currentLocale] localeIdentifier];
  4391 +
  4392 + #if TARGET_OS_IPHONE
  4393 + UIDevice *device = [UIDevice currentDevice];
  4394 + deviceName = [device model];
  4395 + OSName = [device systemName];
  4396 + OSVersion = [device systemVersion];
  4397 +
  4398 + #else
  4399 + deviceName = @"Macintosh";
  4400 + OSName = @"Mac OS X";
  4401 +
  4402 + // From http://www.cocoadev.com/index.pl?DeterminingOSVersion
  4403 + // We won't bother to check for systems prior to 10.4, since ASIHTTPRequest only works on 10.5+
  4404 + OSErr err;
  4405 + SInt32 versionMajor, versionMinor, versionBugFix;
  4406 + err = Gestalt(gestaltSystemVersionMajor, &versionMajor);
  4407 + if (err != noErr) return nil;
  4408 + err = Gestalt(gestaltSystemVersionMinor, &versionMinor);
  4409 + if (err != noErr) return nil;
  4410 + err = Gestalt(gestaltSystemVersionBugFix, &versionBugFix);
  4411 + if (err != noErr) return nil;
  4412 + OSVersion = [NSString stringWithFormat:@"%u.%u.%u", versionMajor, versionMinor, versionBugFix];
  4413 + #endif
  4414 +
  4415 + // Takes the form "My Application 1.0 (Macintosh; Mac OS X 10.5.7; en_GB)"
  4416 + [self setDefaultUserAgentString:[NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale]];
4383 } 4417 }
4384 - } else { 4418 + return [[defaultUserAgent retain] autorelease];
4385 - appVersion = (marketingVersionNumber ? marketingVersionNumber : developmentVersionNumber);  
4386 } 4419 }
4387 -  
4388 -  
4389 - NSString *deviceName;  
4390 - NSString *OSName;  
4391 - NSString *OSVersion;  
4392 -  
4393 - NSString *locale = [[NSLocale currentLocale] localeIdentifier];  
4394 -  
4395 -#if TARGET_OS_IPHONE  
4396 - UIDevice *device = [UIDevice currentDevice];  
4397 - deviceName = [device model];  
4398 - OSName = [device systemName];  
4399 - OSVersion = [device systemVersion];  
4400 -  
4401 -#else  
4402 - deviceName = @"Macintosh";  
4403 - OSName = @"Mac OS X";  
4404 -  
4405 - // From http://www.cocoadev.com/index.pl?DeterminingOSVersion  
4406 - // We won't bother to check for systems prior to 10.4, since ASIHTTPRequest only works on 10.5+  
4407 - OSErr err;  
4408 - SInt32 versionMajor, versionMinor, versionBugFix;  
4409 - err = Gestalt(gestaltSystemVersionMajor, &versionMajor);  
4410 - if (err != noErr) return nil;  
4411 - err = Gestalt(gestaltSystemVersionMinor, &versionMinor);  
4412 - if (err != noErr) return nil;  
4413 - err = Gestalt(gestaltSystemVersionBugFix, &versionBugFix);  
4414 - if (err != noErr) return nil;  
4415 - OSVersion = [NSString stringWithFormat:@"%u.%u.%u", versionMajor, versionMinor, versionBugFix];  
4416 -  
4417 -#endif  
4418 - // Takes the form "My Application 1.0 (Macintosh; Mac OS X 10.5.7; en_GB)"  
4419 - [self setDefaultUserAgentString:[NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale]];  
4420 - return defaultUserAgent;  
4421 } 4420 }
4422 4421
4423 + (void)setDefaultUserAgentString:(NSString *)agent 4422 + (void)setDefaultUserAgentString:(NSString *)agent
4424 { 4423 {
4425 - [defaultUserAgent release]; 4424 + @synchronized (self) {
4426 - defaultUserAgent = [agent copy]; 4425 + if (defaultUserAgent == agent) {
  4426 + return;
  4427 + }
  4428 + [defaultUserAgent release];
  4429 + defaultUserAgent = [agent copy];
  4430 + }
4427 } 4431 }
4428 4432
4429 4433
@@ -4671,13 +4675,18 @@ static NSOperationQueue *sharedQueue = nil; @@ -4671,13 +4675,18 @@ static NSOperationQueue *sharedQueue = nil;
4671 4675
4672 + (void)setDefaultCache:(id <ASICacheDelegate>)cache 4676 + (void)setDefaultCache:(id <ASICacheDelegate>)cache
4673 { 4677 {
4674 - [defaultCache release]; 4678 + @synchronized (self) {
4675 - defaultCache = [cache retain]; 4679 + [cache retain];
  4680 + [defaultCache release];
  4681 + defaultCache = cache;
  4682 + }
4676 } 4683 }
4677 4684
4678 + (id <ASICacheDelegate>)defaultCache 4685 + (id <ASICacheDelegate>)defaultCache
4679 { 4686 {
4680 - return defaultCache; 4687 + @synchronized(self) {
  4688 + return [[defaultCache retain] autorelease];
  4689 + }
4681 } 4690 }
4682 4691
4683 4692