diff --git a/ChangeLog b/ChangeLog index 5447f6059..cd1fe688c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-10-17 Richard Frith-Macdonald + + * Source/NSBundle.m: + * Source/NSCalendarDate.m: + * Source/NSFileManager.m: + * Source/NSJSONSerialization.m: + * Source/NSMessagePort.m: + * Source/NSMessagePortNameServer.m: + * Source/NSPropertyList.m: + Avoid autoreleasing things in +initialize when there may be no + autorelease pool present ... we don't want to either leak or + cause recursive loops when we want to log any leaks. + 2012-10-15 Eric Wasylishen * Tests/base/NSArchiver/stringEncoding.m: add test for last commit diff --git a/Source/NSBundle.m b/Source/NSBundle.m index 3217de72d..6e7d923bb 100644 --- a/Source/NSBundle.m +++ b/Source/NSBundle.m @@ -1059,6 +1059,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) if (self == [NSBundle class]) { extern const char *GSPathHandling(const char *); + NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSString *file; const char *mode; NSDictionary *env; @@ -1067,7 +1068,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) /* Ensure we do 'right' path handling while initializing core paths. */ mode = GSPathHandling("right"); - _emptyTable = RETAIN([NSDictionary dictionary]); + _emptyTable = [NSDictionary new]; /* Create basic mapping dictionaries for bootstrapping and * for use if the full ductionaries can't be loaded from the @@ -1127,6 +1128,15 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) */ manager(); + /* Set up tables for bundle lookups + */ + _bundles = NSCreateMapTable(NSObjectMapKeyCallBacks, + NSNonOwnedPointerMapValueCallBacks, 0); + _byClass = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, + NSNonOwnedPointerMapValueCallBacks, 0); + _byIdentifier = NSCreateMapTable(NSObjectMapKeyCallBacks, + NSNonOwnedPointerMapValueCallBacks, 0); + pathCacheLock = [NSLock new]; pathCache = [NSMutableDictionary new]; @@ -1216,6 +1226,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) _loadingBundle = nil; #endif GSPathHandling(mode); + [pool release]; } } @@ -1226,32 +1237,30 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) + (NSArray *) allBundles { NSMutableArray *array = [NSMutableArray arrayWithCapacity: 2]; + NSMapEnumerator enumerate; + void *key; + NSBundle *bundle; [load_lock lock]; if (!_mainBundle) { [self mainBundle]; } - if (_bundles != 0) - { - NSMapEnumerator enumerate; - void *key; - NSBundle *bundle; - enumerate = NSEnumerateMapTable(_bundles); - while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle)) - { - if (bundle->_bundleType == NSBUNDLE_FRAMEWORK) - { - continue; - } - if ([array indexOfObjectIdenticalTo: bundle] == NSNotFound) - { - [array addObject: bundle]; - } - } - NSEndMapTableEnumeration(&enumerate); + enumerate = NSEnumerateMapTable(_bundles); + while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle)) + { + if (bundle->_bundleType == NSBUNDLE_FRAMEWORK) + { + continue; + } + if ([array indexOfObjectIdenticalTo: bundle] == NSNotFound) + { + [array addObject: bundle]; + } } + NSEndMapTableEnumeration(&enumerate); + [load_lock unlock]; return array; } @@ -1631,6 +1640,7 @@ IF_NO_GC( - (id) initWithPath: (NSString*)path { NSString *identifier; + NSBundle *bundle; self = [super init]; @@ -1698,17 +1708,13 @@ IF_NO_GC( /* check if we were already initialized for this directory */ [load_lock lock]; - if (_bundles) + bundle = (NSBundle *)NSMapGet(_bundles, path); + if (bundle != nil) { - NSBundle *bundle = (NSBundle *)NSMapGet(_bundles, path); - - if (bundle != nil) - { - IF_NO_GC([bundle retain];) - [load_lock unlock]; - [self dealloc]; - return bundle; - } + IF_NO_GC([bundle retain];) + [load_lock unlock]; + [self dealloc]; + return bundle; } [load_lock unlock]; @@ -1723,7 +1729,14 @@ IF_NO_GC( } } + /* OK ... this is a new bundle ... need to insert it in the global map + * to be found by this path so that a leter call to -bundleIdentifier + * can work. + */ _path = [path copy]; + [load_lock lock]; + NSMapInsert(_bundles, _path, self); + [load_lock unlock]; if ([[[_path lastPathComponent] pathExtension] isEqual: @"framework"] == YES) { @@ -1740,37 +1753,22 @@ IF_NO_GC( identifier = [self bundleIdentifier]; [load_lock lock]; - if (!_bundles) - { - _bundles = NSCreateMapTable(NSObjectMapKeyCallBacks, - NSNonOwnedPointerMapValueCallBacks, 0); - } - if (!_byClass) - { - /* Used later by framework code. - */ - _byClass = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, - NSNonOwnedPointerMapValueCallBacks, 0); - } - if (!_byIdentifier) - { - _byIdentifier = NSCreateMapTable(NSObjectMapKeyCallBacks, - NSNonOwnedPointerMapValueCallBacks, 0); - } if (identifier != nil) { NSBundle *bundle = (NSBundle *)NSMapGet(_byIdentifier, identifier); - if (bundle != nil) - { - IF_NO_GC([bundle retain];) - [load_lock unlock]; - [self dealloc]; - return bundle; - } - NSMapInsert(_byIdentifier, identifier, self); + if (bundle != self) + { + if (bundle != nil) + { + IF_NO_GC([bundle retain];) + [load_lock unlock]; + [self dealloc]; + return bundle; + } + NSMapInsert(_byIdentifier, identifier, self); + } } - NSMapInsert(_bundles, _path, self); [load_lock unlock]; return self; diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index 9ea6801d7..e8c5c238b 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -349,8 +349,10 @@ GSPrivateTimeNow(void) + (void) initialize { - if (self == [NSCalendarDate class]) + if (self == [NSCalendarDate class] && nil == NSCalendarDateClass) { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + NSCalendarDateClass = self; [self setVersion: 1]; localTZ = RETAIN([NSTimeZone localTimeZone]); @@ -375,6 +377,7 @@ GSPrivateTimeNow(void) [absClass instanceMethodForSelector: abrSEL]; GSObjCAddClassBehavior(self, [NSGDate class]); + [pool release]; } } diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index b0e415ebb..2d39b1fec 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -3116,7 +3116,7 @@ static NSSet *fileKeys = nil; { if (fileKeys == nil) { - fileKeys = [NSSet setWithObjects: + fileKeys = [[NSSet alloc] initWithObjects: NSFileAppendOnly, NSFileCreationDate, NSFileDeviceIdentifier, @@ -3136,7 +3136,6 @@ static NSSet *fileKeys = nil; NSFileSystemNumber, NSFileType, nil]; - IF_NO_GC([fileKeys retain];) } } diff --git a/Source/NSJSONSerialization.m b/Source/NSJSONSerialization.m index 2bdab5a06..3f86ec056 100644 --- a/Source/NSJSONSerialization.m +++ b/Source/NSJSONSerialization.m @@ -721,7 +721,7 @@ static Class NSNullClass; static Class NSNumberClass; static Class NSStringClass; -static NSCharacterSet *escapeSet; +static NSMutableCharacterSet *escapeSet; static inline void writeTabs(NSMutableString *output, NSInteger tabs) @@ -902,10 +902,10 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs) NSStringClass = [NSString class]; NSDictionaryClass = [NSDictionary class]; NSNumberClass = [NSNumber class]; - escapeSet - = [[NSCharacterSet characterSetWithCharactersInString: @"\"\\"] retain]; - boolN = [[NSNumber numberWithBool: NO] retain]; - boolY = [[NSNumber numberWithBool: YES] retain]; + escapeSet = [NSMutableCharacterSet new]; + [escapeSet addCharactersInString: @"\"\\"]; + boolN = [[NSNumber alloc] initWithBool: NO]; + boolY = [[NSNumber alloc] initWithBool: YES]; } + (NSData*) dataWithJSONObject: (id)obj diff --git a/Source/NSMessagePort.m b/Source/NSMessagePort.m index 04dc4d5dc..3761209f3 100644 --- a/Source/NSMessagePort.m +++ b/Source/NSMessagePort.m @@ -1130,6 +1130,7 @@ typedef struct { { if (self == [NSMessagePort class]) { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSFileManager *mgr; NSString *path; NSString *pref; @@ -1180,6 +1181,7 @@ typedef struct { } } } + [pool release]; } } diff --git a/Source/NSMessagePortNameServer.m b/Source/NSMessagePortNameServer.m index 97d177511..db6131bd4 100644 --- a/Source/NSMessagePortNameServer.m +++ b/Source/NSMessagePortNameServer.m @@ -128,6 +128,7 @@ static void clean_up_names(void) { if (self == [NSMessagePortNameServer class]) { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSFileManager *mgr; NSString *path; NSString *pref; @@ -177,6 +178,7 @@ static void clean_up_names(void) } } } + [pool release]; } } diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index 4b78ddc7f..94c07a865 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -591,30 +591,28 @@ static NSCharacterSet *xmlQuotables = nil; static void setupQuotables(void) { - if (oldQuotables == nil) + if (nil == oldQuotables) { NSMutableCharacterSet *s; /* The '$', '.', '/' and '_' characters used to be OK to use in * property lists, but OSX now quotes them, so we follow suite. */ - s = [[NSCharacterSet characterSetWithCharactersInString: + s = [NSMutableCharacterSet new]; + [s addCharactersInString: @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - @"abcdefghijklmnopqrstuvwxyz"] - mutableCopy]; + @"abcdefghijklmnopqrstuvwxyz"]; [s invert]; - oldQuotables = [s copy]; - RELEASE(s); + oldQuotables = s; - s = [[NSCharacterSet characterSetWithCharactersInString: - @"&<>'\\\""] mutableCopy]; + s = [NSMutableCharacterSet new]; + [s addCharactersInString: @"&<>'\\\""]; [s addCharactersInRange: NSMakeRange(0x0001, 0x001f)]; [s removeCharactersInRange: NSMakeRange(0x0009, 0x0002)]; [s removeCharactersInRange: NSMakeRange(0x000D, 0x0001)]; [s addCharactersInRange: NSMakeRange(0xD800, 0x07FF)]; [s addCharactersInRange: NSMakeRange(0xFFFE, 0x0002)]; - xmlQuotables = [s copy]; - RELEASE(s); + xmlQuotables = s; } }