diff --git a/ChangeLog b/ChangeLog index c040394bd..dda891bf4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2000-10-27 Richard Frith-Macdonald + + * Source/NSURLHandle.m: Make class registration thread safe. + Tidy initialisation to use designated initialiser. + 2000-10-27 Adam Fedor * Added localization support diff --git a/Documentation/gsdoc/NSURL.gsdoc b/Documentation/gsdoc/NSURL.gsdoc index 2c23f2e32..66c0c47ca 100644 --- a/Documentation/gsdoc/NSURL.gsdoc +++ b/Documentation/gsdoc/NSURL.gsdoc @@ -51,6 +51,22 @@ usingCache: shouldUseCache + Loads the resource data for the specified URL. +

+ If shouldUseCache is YES then an attempt + will be made to locate a cached NSURLHandle to provide the + resource data, otherwise a new handle will be created and + cached. +

+

+ If the handle does not have the data available, it will be + asked to load the data in the background by calling its + loadInBackground method. +

+

+ The specified client (if non-nil) will be set up to recieve + notifications of the progress fo the background load process. +

diff --git a/Documentation/gsdoc/NSURL.html b/Documentation/gsdoc/NSURL.html index 59dbd7fd6..7f789fecf 100644 --- a/Documentation/gsdoc/NSURL.html +++ b/Documentation/gsdoc/NSURL.html @@ -71,6 +71,28 @@

loadResourceDataNotifyingClient:usingCache:

- (void) loadResourceDataNotifyingClient: (id)client usingCache: (BOOL)shouldUseCache;
+ Loads the resource data for the specified URL. +

+ + If shouldUseCache is YES then an attempt + will be made to locate a cached NSURLHandle to provide the + resource data, otherwise a new handle will be created and + cached. +

+ +

+ + If the handle does not have the data available, it will be + asked to load the data in the background by calling its + loadInBackground method. +

+ +

+ + The specified client (if non-nil) will be set up to recieve + notifications of the progress fo the background load process. +

+

parameterString

diff --git a/Source/NSURL.m b/Source/NSURL.m index 62ad5aff3..344c46c02 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -591,7 +591,6 @@ NSString *NSURLPartKey_query = @"query"; NSLog(@"*_baseURL: %@", [[url baseURL] description]); } -//----------------------------------------------------------------------------- - (void) loadResourceDataNotifyingClient: (id)client usingCache: (BOOL)shouldUseCache { @@ -635,7 +634,6 @@ NSString *NSURLPartKey_query = @"query"; return data; } -//----------------------------------------------------------------------------- - (NSURLHandle*) URLHandleUsingCache: (BOOL)shouldUseCache { NSURLHandle *handle = nil; @@ -657,15 +655,13 @@ NSString *NSURLPartKey_query = @"query"; return handle; } -//----------------------------------------------------------------------------- - (BOOL) setResourceData: (NSData*)data { NSURLHandle *handle = [self URLHandleUsingCache: YES]; - return [handle writeData: data]; + return (handle == nil) ? NO : [handle writeData: data]; } -//----------------------------------------------------------------------------- - (id) propertyForKey: (NSString*)propertyKey { NSURLHandle *handle = [self URLHandleUsingCache: YES]; @@ -673,7 +669,6 @@ NSString *NSURLPartKey_query = @"query"; return [handle propertyForKey: propertyKey]; } -//----------------------------------------------------------------------------- - (BOOL) setProperty: (id)property forKey: (NSString*)propertyKey; { diff --git a/Source/NSURLHandle.m b/Source/NSURLHandle.m index ee8293e3b..e2ea71aa8 100644 --- a/Source/NSURLHandle.m +++ b/Source/NSURLHandle.m @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,9 @@ @implementation NSURLHandle +static NSLock *registryLock = nil; static NSMutableArray *registry = nil; +static Class NSURLHandleClass = 0; + (NSURLHandle*) cachedHandleForURL: (NSURL*)url { @@ -47,11 +50,18 @@ static NSMutableArray *registry = nil; * Each subclass is supposed to do its own caching, so we must * find the correct subclass and ask it for its cached handle. */ - if (self == [NSURLHandle class]) + if (self == NSURLHandleClass) { Class c = [self URLHandleClassForURL: url]; - return [c cachedHandleForURL: url]; + if (c == self || c == 0) + { + return nil; + } + else + { + return [c cachedHandleForURL: url]; + } } else { @@ -72,7 +82,9 @@ static NSMutableArray *registry = nil; { if (self == [NSURLHandle class]) { + NSURLHandleClass = self; registry = [NSMutableArray new]; + registryLock = [NSLock new]; [self registerURLHandleClass: [GSFileURLHandle class]]; } } @@ -84,13 +96,18 @@ static NSMutableArray *registry = nil; * Re-adding a class moves it to the end of the registry - so it will * be used in preference to any class added earlier. */ + [registryLock lock]; [registry removeObjectIdenticalTo: urlHandleSubclass]; [registry addObject: urlHandleSubclass]; + [registryLock unlock]; } + (Class) URLHandleClassForURL: (NSURL*)url { - unsigned count = [registry count]; + unsigned count; + + [registryLock lock]; + count = [registry count]; /* * Find a class to handle the URL, try most recently registered first. @@ -101,9 +118,11 @@ static NSMutableArray *registry = nil; if ([found canInitWithURL: url] == YES) { + [registryLock unlock]; return (Class)found; } } + [registryLock unlock]; return 0; } @@ -245,17 +264,16 @@ static NSMutableArray *registry = nil; - (id) init { - _status = NSURLHandleNotLoaded; - _clients = [NSMutableArray new]; - _data = [NSMutableData new]; - return self; + return [self initWithURL: nil cached: NO]; } - (id) initWithURL: (NSURL*)url cached: (BOOL)cached { - [self subclassResponsibility: _cmd]; - return nil; + _status = NSURLHandleNotLoaded; + _clients = [NSMutableArray new]; + _data = [NSMutableData new]; + return self; } - (void) loadInBackground @@ -394,14 +412,13 @@ static NSMutableDictionary *fileCache = nil; return self; } } - self = [super init]; - if (self != nil) + + if ((self = [super initWithURL: url cached: cached]) != nil) { _path = [path copy]; if (cached == YES) { [fileCache setObject: self forKey: _path]; - RELEASE(self); } } return self;